Chris Abbey writes:
> So what part of garbage collection actually releases the resources
> of an object? java/lang/Object.finalize(); The way gc frees up
> resources is that it calls finalize on any object that it has
> detected is garbage (is not reachable) before it goes through and
> takes the object apart.
> [...]
> Why not finalize the object ourselves?

Your note, especially the part I quoted, strongly implies that
java/lang/Object.finalize() causes the object to be garbage collected.
It doesn't.  If properly written, finalize() does free any external
(to the JVM) resources held by the object, and while that's good, it
doesn't solve problems of memory growth.

All the JLS promises is that finalize() will be called before an
object is garbage collected.  Section 12.6.1 of the JLS
        (http://java.sun.com/docs/books/jls/html/12.doc.html)
is very clear that the converse is not true:

        "Explicit invocation of a finalizer ignores the current state
         of the object and does not change the state of the object from
         unfinalized or finalizable to finalized."

Since only finalized objects can be garbage collected, that means that
explicitly calling finalize() doesn't get you any closer to garbage
collection.  A corollary of this is that, if you call finalize()
explicitly, the GC is required by the JLS to call finalize() *again*
before it garbage collects the item.

Also, JLS 20.1 explicitly states that it is allowed for finalize() to
create references to the object that will cause it to be reachable
(and thus prevent the object from being garbage collected).  Later in
20.1, it reiterates that garbage collection is a separate phase after
finalization, and there are lots of things that can get between the
two.

Now, it would be possible for the JVM to recognize an explicit
invocation of finalize() as a kind of hint.  It could put that object
on a list of objects to be checked frequently to see whether it is
garbage or not, and free resources if it is.  There are two problems
with that.

    1. The GC would have to do a complete GC pass to determine whether
    this one object is garbage.  There are reference-counting tricks that
    could optimize this in some cases, but not in general: among other
    difficulties, finalize() is allowed to create a new reference to the
    object.  For the GCs I know of, giving a "collect me soon" hint
    requires a radical increase in the frequency at which the GC runs.  If
    "efficient" programmers used these hints often, the GC would be
    running almost all the time, leading to miserable performance.  Even
    if you could find a GC architecture that would support such hinting,
    you would basically require all JVMs to use that type of GC -- which
    is a huge constraint on JVM designers.

    2. If you're going to give a hint, why use finalize() as the hint?
    Then finalize would always get called twice (once as the hint and then
    again as required by the JLS) for every object that was "hinted."  It
    would be clearer and possibly more efficient to use a different method
    whose sole purpose is to give the hint.

-----------------------

Here's an alternative approach that works in some cases, if you're
willing to do explicit memory management.

Garbage collectors run only in proportion to the number of allocations
performed.  So create a class MallocFoo that keeps a pool of your Foo
objects, and call MallocFoo.new() to allocate one and MallocFoo.free()
to return it to the pool when you're done with it.  If there are
external resources involved, MallocFoo can get them and release them
as needed.

This works fine in all cases *except* the case where you need a lot of
resources for a short time and then don't need them again for a "long
time."  Most programs aren't like that, but for those that are, the
problem could be solved with a System.forceGc() method.  Such a method
would also be useful to people who don't want to or need to keep track
of exactly when each reference dies out.  Since current
implementations of Java never shrink their memory images anyway, that
would be another necessary part of forceGc().

I imagine that a forceGc() which does what I just described would be
very inefficient on some JVMs, and it might also impose constraints on
JVM optimization even for programs that didn't use forceGc(), since
shrinking the memory image implies rewriting (potentially all)
references -- something not all GC schemes can do well or at all.

Bottom line: I know of no way to force garbage collection in Java.

Best,
daniel dulitz

Valley Technologies, Inc.               Peak Performance Real-Time DSP
State College, PA


----------------------------------------------------------------------
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to