From: markspace on
Tom Anderson wrote:
> i believe a
> PhantomReference is likely to tell you about collection sooner than a
> finalizer would.


The opposite. Finalizers get run as soon as the object becomes eligible
for GC, on the first GC pass. Then the object is freed up on the second
pass, then "sometime maybe later" the PhantomReference is enqueued.

The difference is that the finalizer is run with the object is still
"live" and in memory. The phantom reference only appears well after the
object is completely gone, and totally GC'd too.

In summary:

finalizer := about to be GC'd
phantom := "He's dead, Jim."

From: Lew on
Tom Anderson wrote:
>> i believe a PhantomReference is likely to tell you about collection
>> sooner than a finalizer would.

markspace wrote:
> The opposite. Finalizers
might
> get run as soon as the object becomes eligible
> for GC, on the first GC pass

or later.

> Then the object is freed up on the second pass,

or later,

> then "sometime maybe later" the PhantomReference is enqueued.

The Javadocs for 'finalize()' point out that after that method runs,
"no further action is taken until the Java virtual machine has again
determined that there is no longer any means by which this object can be
accessed by any thread that has not yet died, including possible actions by
other objects or classes which are ready to be finalized, at which point the
object may be discarded."

Since there is no guarantee that other finalizers will run at any given GC
pass, it might take a few passes after a particular object's has run before
the GC *may* (not definitely will) discard it.

> The difference is that the finalizer is run with the object is still
> "live" and in memory. The phantom reference only appears well after the
> object is completely gone, and totally GC'd too.
>
> In summary:
>
> finalizer := about to be GC'd
> phantom := "He's dead, Jim."

--
Lew
From: Tom Anderson on
On Tue, 1 Dec 2009, Lew wrote:

> Tom Anderson wrote:
>>> i believe a PhantomReference is likely to tell you about collection sooner
>>> than a finalizer would.
>
> markspace wrote:
>> The opposite. Finalizers
> might
>> get run as soon as the object becomes eligible for GC, on the first GC pass
>
> or later.
>
>> Then the object is freed up on the second pass,
>
> or later,
>
>> then "sometime maybe later" the PhantomReference is enqueued.
>
> The Javadocs for 'finalize()' point out that after that method runs,
> "no further action is taken until the Java virtual machine has again
> determined that there is no longer any means by which this object can be
> accessed by any thread that has not yet died, including possible actions by
> other objects or classes which are ready to be finalized, at which point the
> object may be discarded."
>
> Since there is no guarantee that other finalizers will run at any given GC
> pass, it might take a few passes after a particular object's has run before
> the GC *may* (not definitely will) discard it.

Maybe using both is the solution. And since objects become weakly
reachable *before* finalization, one of those too!

tom

--
around here life is an ambulance eternally carting some dumb idea between
two passing-out brains -- R. Beef Kazenzakis
From: Thomas Pornin on
According to markspace <nospam(a)nowhere.com>:
> The opposite. Finalizers get run as soon as the object becomes eligible
> for GC, on the first GC pass. Then the object is freed up on the second
> pass, then "sometime maybe later" the PhantomReference is enqueued.

However, an object with a trivial finalize() (i.e. Object.finalize() is
not overridden) may become eligible for GC handling faster. It depends
on the GC technology. In my own GC, allocation is generational, but
finalizable objects (those which have a non-trivial finalize) are
allocated in the old generation, and are collected less often. Since
even Sun's JVM offers several distinct GC implementations, there is no
weel-defined answer to that question.


--Thomas Pornin
From: Dan on
On Nov 30, 10:26 pm, "John B. Matthews" <nos...(a)nospam.invalid> wrote:
> They also mention "a custom JVMPI (JVM Profiler Interface) agent." I'm
> guessing that's the trash can icon in NetBeans' profiler.

This is exactly what I was looking for! The JVMPI declares the
following method (http://java.sun.com/j2se/1.4.2/docs/guide/jvmpi/
jvmpi.html#RunGC):

void (*RunGC)(void);
"Called by the profiler to force a complete garbage collection. This
function must not be called when GC is disabled."

JVMPI is depreciated in Java 1.5 and is gone in 1.6. It was replaced
with JVMTI which has the following method (http://java.sun.com/javase/
6/docs/platform/jvmti/jvmti.html#ForceGarbageCollection):

jvmtiError ForceGarbageCollection(jvmtiEnv* env)
"Force the VM to perform a garbage collection. The garbage collection
is as complete as possible. This function does not cause finalizers to
be run. This function does not return until the garbage collection is
finished."

This solves the mystery of how Eclipse, Netbeans, and jProfiler can
force a GC; but unfortunately, it can't be used to test my finalizer.

Thanks!

-Dan