Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Forcing System.gc()

Reply
Thread Tools

Forcing System.gc()

 
 
Eric Sosman
Guest
Posts: n/a
 
      06-08-2007
Matt Humphrey wrote On 06/07/07 21:19,:
> "Philipp Leitner" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed) ups.com...
> |> I am wondering if I may not be able to improve performance by System.gc()
> in
> | > some "right" places in my code (wherever those might be!). It seems to
> me
> | > though, that the gc facilities in Java are so good, that this is
> something
> | > best left up to the JVM, and NOT mess with putting System.gc() in
> anyplace?
> |
> | Probably. But you can never 'force' the JVM to do garbage collection.
> | System.gc() will only 'suggest' that now may be a good time to do GC
> | (but under certain circumstances, I think it has to do with system
> | load, the JVM might simply ignore the call). Anyway, I think the cost
> | for calling System.gc() is not huge, so perhaps I think it might be
> | worth a try.
> |
> | I for myself remember having used System.gc() exactly once so far - in
> | one project I was running >200 Unit Tests, and every test case was
> | creating an in-memory representation of a WSDL file and compiled XML
> | Schemata using XMLBeans. At some point in the test run the JVM just
> | stopped with OutOfMemory. Putting a System.gc() at the end of every
> | single test case solved the problem just nice.
>
> Can you explain how your request for gc would prevent an OutOfMemory error?
> I thought that OutOfMemory occurs only when gc cannot reclaim any more--it
> is never necessary to request gc to prevent OutOfMemory.


Might a really memory-hungry finalize() cause such
a thing? I imagine that if finalization uses a lot of
memory, running GC early could schedule deceased objects
for finalization while memory is still plentiful, while
postponing GC until memory is scarce might leave too
little for the finalizers' use. (I hasten to add that
I don't say things *would* play out this way, just that
it seems to me that they might -- I'm entirely ready to
be corrected by someone who knows better.)

A memory-hungry finalizer seems an awfully silly
thing to write -- but that doesn't mean nobody writes
them ...

--
http://www.velocityreviews.com/forums/(E-Mail Removed)

 
Reply With Quote
 
 
 
 
Mark Space
Guest
Posts: n/a
 
      06-08-2007
Matt Humphrey wrote:

> Can you explain how your request for gc would prevent an OutOfMemory error?
> I thought that OutOfMemory occurs only when gc cannot reclaim any more--it
> is never necessary to request gc to prevent OutOfMemory.



Would it be possible that long running code without garbage collection
left the heap so fragmented that the largest available memory block
wouldn't hold some object that needed to be allocated? That's all I can
think of. I don't know enough about JVM and memory allocation to know
if this is even a likely scenario...
 
Reply With Quote
 
 
 
 
Twisted
Guest
Posts: n/a
 
      06-08-2007
On Jun 8, 3:33 pm, Mark Space <(E-Mail Removed)> wrote:
> Matt Humphrey wrote:
> > Can you explain how your request for gc would prevent an OutOfMemory error?
> > I thought that OutOfMemory occurs only when gc cannot reclaim any more--it
> > is never necessary to request gc to prevent OutOfMemory.

>
> Would it be possible that long running code without garbage collection
> left the heap so fragmented that the largest available memory block
> wouldn't hold some object that needed to be allocated? That's all I can
> think of. I don't know enough about JVM and memory allocation to know
> if this is even a likely scenario...


Shouldn't be. The thorough GC tried before throwing OOME should
compact all the surviving objects into one or two contiguous blocks
(maybe two with generational GC). Heap fragmentation is for C++
programmers to fret about.

As for a finalizer allocating memory, I'd sort of assumed an absence
of such questionable code. If there is one, though, it could explain a
thing or two. And demonstrate why finalizers are evil, and should only
ever be used to make sure file handles and such are (eventually)
released and never to do anything more complicated than close a stream
here or null out a reference there.

 
Reply With Quote
 
Mark Space
Guest
Posts: n/a
 
      06-09-2007
Twisted wrote:

>
> Shouldn't be. The thorough GC tried before throwing OOME should
> compact all the surviving objects into one or two contiguous blocks
> (maybe two with generational GC). Heap fragmentation is for C++
> programmers to fret about.


Useful to know, thanks. ^_^ I suppose then that Java references can't
be pointers at all, because moving objects in the heap would invalidate
those pointers. And going through the code and updating all references
on the fly seems... ugly, to say the least. Maybe references work
something like handles in the old Mac OS? Pointers to pointers, where
the second pointer is the thing that gets updated when objects on the
heap are re-allocated or moved.
 
Reply With Quote
 
Stefan Ram
Guest
Posts: n/a
 
      06-09-2007
Mark Space <(E-Mail Removed)> writes:
>I suppose then that Java references can't be pointers at all,
>because moving objects in the heap would invalidate those pointers.


»(...) reference values (...) are pointers«

JLS3, 4.3.1.

http://java.sun.com/docs/books/jls/t...ues.html#4.3.1

 
Reply With Quote
 
Twisted
Guest
Posts: n/a
 
      06-09-2007
On Jun 8, 9:39 pm, (E-Mail Removed)-berlin.de (Stefan Ram) wrote:
> Mark Space <(E-Mail Removed)> writes:
> >I suppose then that Java references can't be pointers at all,
> >because moving objects in the heap would invalidate those pointers.

>
> »(...) reference values (...) are pointers«
>
> JLS3, 4.3.1.
>
> http://java.sun.com/docs/books/jls/t...ypesValues.htm...


Either it uses double indirection, or (more likely) it updates all the
references when it compacts an object. It can do this -- the gc will
have found those references when mapping the object graph and deciding
whether the object was garbage or not.

 
Reply With Quote
 
=?ISO-8859-1?Q?Arne_Vajh=F8j?=
Guest
Posts: n/a
 
      06-09-2007
Mark Space wrote:
> Twisted wrote:
>> Shouldn't be. The thorough GC tried before throwing OOME should
>> compact all the surviving objects into one or two contiguous blocks
>> (maybe two with generational GC). Heap fragmentation is for C++
>> programmers to fret about.

>
> Useful to know, thanks. ^_^ I suppose then that Java references can't
> be pointers at all, because moving objects in the heap would invalidate
> those pointers. And going through the code and updating all references
> on the fly seems... ugly, to say the least. Maybe references work
> something like handles in the old Mac OS? Pointers to pointers, where
> the second pointer is the thing that gets updated when objects on the
> heap are re-allocated or moved.


I think that it is left to the JVM implementation to decide
how is will do it.

Note that it already to go through a lot of stuff to find out
what can be GC'ed.

Possibility of reuse !

Arne




 
Reply With Quote
 
Twisted
Guest
Posts: n/a
 
      06-10-2007
On Jun 9, 2:32 pm, Arne Vajhøj <(E-Mail Removed)> wrote:
> I think that it is left to the JVM implementation to decide
> how is will do it.
>
> Note that it already to go through a lot of stuff to find out
> what can be GC'ed.
>
> Possibility of reuse !


Certainty of reuse. Sun's VM (the defacto reference implementation)
definitely does do this. With generational GC, it determines if an
object is still live, then copies live objects to a growing contiguous
block of them in memory, which becomes the mature generation or some
such terminology. At the time it copies a particular object it has
pointers to that object's inbound references in memory, from when it
determined its reachability, and on copying it diddles them to point
to the object's new location, presumably while suspending the running
code (so-called "stop the world" gc). It may do incremental GCs that
don't copy objects or "stop the world" depending on settings, with
more thorough, "stop the world" compacting collections when necessary
(due to fragmentation, for instance).

 
Reply With Quote
 
David Gourley
Guest
Posts: n/a
 
      06-11-2007
Twisted wrote:

>
>
> Shouldn't be. The thorough GC tried before throwing OOME should
> compact all the surviving objects into one or two contiguous blocks
> (maybe two with generational GC). Heap fragmentation is for C++
> programmers to fret about.
>


But there is one big, big assumption here: that the only cause of OOME
is exhausting the (Java) heap. Actually this is one of my biggest
annoyances about Java, especially 32-bit implementations.

You can get OOME attempting to create a thread if there isn't memory to
create the thread's stack (which is actually a native memory issue).

You can get OOME from some mixed language classes if the *native* memory
can't get created associated with instances of those classes (there are
some of these in the java library that allocate native memory as well as
Java memory - always close these objects and don't leave for finalisation).

The annoying thing is I've seen situations where OOME is caused by
unfinalized objects with native memory associated which exhaust the
process's address space (without* causing a garbage collect (as garbage
collection is triggered by behaviour of the Java heap, not the overall
address space of the process). It would be good to have some kind of
setting to trigger a garbage collect if a process's size hit some kind
of threshold as well...

Dave

 
Reply With Quote
 
Twisted
Guest
Posts: n/a
 
      06-12-2007
On Jun 11, 5:20 pm, David Gourley <(E-Mail Removed)>
wrote:
> The annoying thing is I've seen situations where OOME is caused by
> unfinalized objects with native memory associated which exhaust the
> process's address space (without* causing a garbage collect (as garbage
> collection is triggered by behaviour of the Java heap, not the overall
> address space of the process). It would be good to have some kind of
> setting to trigger a garbage collect if a process's size hit some kind
> of threshold as well...


This is real screwy. The JVM *should* stop the world and do a complete
gc and finalization and repeat gc and finalization until nothing new
shows up as garbage, when it is about to throw OOME *for any reason*,
and then retry the allocation, before then actually throwing OOME.
(This would require, I suppose, JNI code to call a malloc-substitute
that does this stuff behind the scenes and retries before returning
NULL, or in C++ a custom operator-new that does likewise before
throwing bad_alloc. If malloc and new are already substituted with
versions that generate OOME in the JVM automatically on failure in the
JNI environment, then this is (comparatively) trivial. Otherwise it
may well be nontrivial and likely will not be back-compatible with
legacy JNI-using code.)

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
forcing one connection Blacklab Wireless Networking 5 10-08-2005 01:21 AM
Forcing password manager to save usernames/passwords for secure sites Jim Firefox 1 05-08-2005 12:04 PM
Forcing links to open in tab instead of new window? fety Firefox 7 03-04-2005 08:34 AM
Re: Anyway of Forcing a Specifc TabPage in a Tabcontrol to Display? mdb ASP .Net 3 09-20-2004 12:59 PM
Forcing native 802.1x supplicant to re-auth??! Tony Wireless Networking 3 07-07-2004 11:35 PM



Advertisments