On 12/28/06, Weldon Washburn <[EMAIL PROTECTED]> wrote:
On 12/27/06, Geir Magnusson Jr. <[EMAIL PROTECTED]> wrote> [snip] > Why can't we simply mimic the rational behavior of the RI and other > production VMs and leave it at that? > > geir I agree. To discover what other JVMs do, I created a very simple finalizer probe then put it in JIRA HARMONY-2908. I ran this probe on Sun JVM 1.5.0_07. Below are the results. It would be good if someone can run this probe on other JVM/OS combinations. The probe is single threaded and has three different execution modes ("java Finx 0", "java Finx 1" and "java Finx 2"). By running each of the modes on WindowsXP and using Microsoft's Process Viewer, one can learn what the different JVM threads are doing. More on this later. Mode 0 This mode intentionally does not create any finalizable objects. The main() method simply runs a cpu intensive workload forever. After every 1000000 loops main() will print a distinctive string that includes a loop count. Mode 1 main() creates 100K finalizable objects that are intentionally shoved into a state where their finalizer needs to be called. main() then proceeds to run the same cpu intensive workload as above. The finalize() method will execute just one call of the same cpu intensive workload then returns. This simulates a short running finalizer. finalize() prints a distinctive string to make it easy to quickly read the output which is comingled with main(). Mode 2 This mode is identical to Mode 1 except the finalize() method calls the cpu intensive workload endlessly. The above describes how the probe is constructed. Below are observations from running this probe on Sun 1.5.0 JVM. Mode 0 There are seven threads. Thread 0 consumes 99% of the total cpu time. And is executing in user mode 100% of the time. Most likely this is the java app thread running main(). All the remaining threads do not accumulate any significant cpu time. Mode 1 There are seven threads. Thread 0 accumulates roughly 2% of total cpu time. Thread 3 accumulates the other 98%. Process Viewer reports Thread 3 having "above normal" priority. (I have not chased down the mapping from Process Viewer priority to win API priority). At the top of the finalize() method a static variable is incremented then printed out. This allows us to watch a rolling count of how many objects have been finalized. Watching the console output for a few minutes, it looks like about 9000 objects are finalized in the same time period that main() completes 100 loops. Since both main() and finalize() are running the same workload, it looks like Thread 3 with "above normal" priority is the thread running the finalizers. The disparity between 90:1 on console output and 50:1 in Process Viewer is probably sampling noise. Also, it looks like Thread 0 is running main() just like it was in Mode 0. Mode 2 Again the JVM is running exactly 7 threads. Only the one object's finalize() method is ever called. Process Viewer shows Thread 3 has "above normal" priority and accumulating roughly 99% of the cpu time. Watching the console output for a few minutes, it look like 2600 finalize() loops to 15 main loops. It appears that no additional threads are created to handle to remaining 99,999 waiting finalizable objects. These objects appear to be blocked waiting for the first object to finish. Also it looks like Thread 0 is running main() just like Mode 0 and 1. Given that Process Viewer shows that Thread 0 continuously and slowly accumulates CPU time, it appears that main() is not suspended but continues to make forward progress.
Very interesting. Thanks for the probation. I think GCv5 finalization subsystem does similarly. Thanks, xiaofeng
