On Wed, 6 Jan 1999, Chris Abbey wrote:
> John (& all),
> Sorry I didn't jump into this thread earlier, but the s:n on this list
> has pushed it down my reading priority list ... way down.
Thanks Chris: I'm glad you stepped in. I've changed mine to match yours
(but am now calling it G).
I have two systems here, results differ:
[summer@emu data]$ java_g G | less
[summer@emu data]$ jikes -d ~/Classes/ G.java && jre G
[summer@emu data]$ jre G
[summer@emu data]$ java G
finalize
[summer@emu data]$ java -fullversion
java full version "stevemw:08/29/98-05:16"
[summer@possum data]$ java G
[summer@possum data]$ jre G
[summer@possum data]$ java G
[summer@possum data]$ jre G
[summer@possum data]$ java -fullversion
java full version "Linux_JDK_1.1.7_v1a_green_threads"
[summer@possum data]$
In eyeballing the trace, I changed line 9 to this:
System.out.print("\nfinalize\n");
as I got some output (on emu) and "finalize" was separated from its
followong newline.
Since it works on emu running with java_g, I'm not posting its trace.
> John's understanding of finalizer and runFinalizersOnExit as I've
> understood him to state it in this thread matches my own interpretation of the
> Java Language spec and JVM spec in this regard. If runFinalizersOnExit is set
> then the finalizer must be called; come hell or high water, that code should
> be given the opportunity to run at some point. It could be when the GC needs to
> purge memory inorder to allocate a request or by explicit call to the API
> java/lang/Runtime.gc()V, or when the runtime is exiting. Note that if the gc
> doesn't have to purge memory to satisfy a request I don't believe it will
> finalize an object, put it on the queue maybe, but not actually do it.
> I don't have my hands on a functional Linux box for a few days, so I
> tested this on Sun's 1.1.6N reference implementation on WinNT. Can someone
> else (John?) run these tests on the blackdown port? Inorder to really test
> this we need to trace the method dispatching. To do this we need to run with
> the debugable build of the java runtime, java_g (jre_g does not allow method
> tracing????) and we need to flip the switch to turn on the method tracing with
> -tm on command line, or the java/lang/Runtime.traceMethodCalls(Z)V API. The
> command line switch is tedious in that you have to wade through all the
> runtime initialization calls, which aren't very interesting to us so I'll go
> with the API.
> I've modified John's posted testcase code as follows:
> --begin F.java--
> 00:public class F
> 01:{
> 02: static //make this code part of "F.<clinit>()V"
> 03: {
> 04: Runtime.getRuntime().traceMethodCalls(true); //activate method dispatch
>trace
> 05: }
> 06: protected void finalize() throws Throwable
> 07: {
> 08:// System.out.println("finalize"); //took too much time, no longer needed
> 09: super.finalize();
> 10: }
> 11: public static void main(String[] args) throws Throwable
> 12: {
> 13: F f = new F();
> 14:// System.runFinalizersOnExit(true); //redundant
> 15: Runtime.getRuntime().runFinalizersOnExit(true);
> 16: f = null;
> 17:// System.gc(); //not needed
> 18: }
> 19:}
> --end F.java--
>
> Then ran it: (all lines begining with '#' are the output, those with '>'
> are my comments to explain what's happening for those unfamiliar with this
> level of the JVM.)
>
> E:\TEMP\New Folder>javac F.java
>
> E:\TEMP\New Folder>java_g F
> # main [ 1] | < java/lang/Runtime.traceMethodCalls(Z)V returning
> # main [ 0] < F.<clinit>()V returning
> >class init & therefore load has just finished, so now start the actual pgm
> # main [ 0] > F.main([Ljava/lang/String;)V (1) entered
> >gotta construct an instance first
> # main [ 1] | > F.<init>()V (1) entered
> >superclass ctor
> # main [ 2] | | > java/lang/Object.<init>()V (1) entered
> # main [ 2] | | < java/lang/Object.<init>()V returning
> # main [ 1] | < F.<init>()V returning
> >line 15
> # main [ 1] | > java/lang/Runtime.getRuntime()Ljava/lang/Runtime; (0) entered
> # main [ 1] | < java/lang/Runtime.getRuntime()Ljava/lang/Runtime; returning
> >still line 15
> # main [ 1] | > java/lang/Runtime.runFinalizersOnExit(Z)V (1) entered
> >within the code for runFinalizersOnExit
> > first check to see if the SecurityManager will let you toggle this
> # main [ 2] | | > java/lang/System.getSecurityManager()Ljava/lang/SecurityManager;
>(0) entered
> # main [ 2] | | < java/lang/System.getSecurityManager()Ljava/lang/SecurityManager;
>returning
> >apparently it will... so call the native code that actually toggles it
> # main [ 2] | | > java/lang/Runtime.runFinalizersOnExit0(Z)V (1) entered
> # main [ 2] | | < java/lang/Runtime.runFinalizersOnExit0(Z)V returning
> # main [ 1] | < java/lang/Runtime.runFinalizersOnExit(Z)V returning
> # main [ 0] < F.main([Ljava/lang/String;)V returning
> >that's the end of main, so begin the runtime exit processes
> > finalize all objects still live
> # main [ 0] > F.finalize()V (1) entered
> >super.finalize() call on line 9
> # main [ 1] | > java/lang/Object.finalize()V (1) entered
> # main [ 1] | < java/lang/Object.finalize()V returning
> # main [ 0] < F.finalize()V returning
> >now finalize System objects, start with System.in
> # main [ 0] > java/io/FileInputStream.finalize()V (1) entered
> # main [ 0] < java/io/FileInputStream.finalize()V returning
> >then System.out
> # main [ 0] > java/io/FileOutputStream.finalize()V (1) entered
> # main [ 1] | > java/io/OutputStream.flush()V (1) entered
> # main [ 1] | < java/io/OutputStream.flush()V returning
> # main [ 0] < java/io/FileOutputStream.finalize()V returning
> >and System.err
> # main [ 0] > java/io/FileOutputStream.finalize()V (1) entered
> # main [ 1] | > java/io/OutputStream.flush()V (1) entered
> # main [ 1] | < java/io/OutputStream.flush()V returning
> # main [ 0] < java/io/FileOutputStream.finalize()V returning
> >that's all
> E:\TEMP\New Folder>
Here's mine:
[summer@possum data]$ java_g G
# main [ 1] | < java/lang/Runtime.traceMethodCalls(Z)V returning
# main [ 0] < G.<clinit>()V returning
# main [ 0] > G.main([Ljava/lang/String;)V (1) entered
# main [ 1] | > G.<init>()V (1) entered
# main [ 2] | | > java/lang/Object.<init>()V (1) entered
# main [ 2] | | < java/lang/Object.<init>()V returning
# main [ 1] | < G.<init>()V returning
# main [ 1] | > java/lang/Runtime.getRuntime()Ljava/lang/Runtime; (0) entered
# main [ 1] | < java/lang/Runtime.getRuntime()Ljava/lang/Runtime; returning
# main [ 1] | > java/lang/Runtime.runFinalizersOnExit(Z)V (1) entered
# main [ 2] | | > java/lang/System.getSecurityManager()Ljava/lang/SecurityManager; (0)
entered
# main [ 2] | | < java/lang/System.getSecurityManager()Ljava/lang/SecurityManager;
returning
# main [ 2] | | > java/lang/Runtime.runFinalizersOnExit0(Z)V (1) entered
# main [ 2] | | < java/lang/Runtime.runFinalizersOnExit0(Z)V returning
# main [ 1] | < java/lang/Runtime.runFinalizersOnExit(Z)V returning
# main [ 0] < G.main([Ljava/lang/String;)V returning
[summer@possum data]$
I've not looked closely at what happens on emu, but it's voluminous and
shows my finalizer being called.
Just for the hell of it, I compiled with javac on both machines (I normally
run jikes): results are the same (finalizer called/notcalled, didn't look
at the trace).
--
Cheers
John Summerfield
http://os2.ami.com.au/os2/ for OS/2 support.
Configuration, networking, combined IBM ftpsites index.