The Source for Java Technology Collaboration
User: Password:



Jack Shirazi's Blog

An incredibly useful JVM change suggestion

Posted by jacksjpt on May 25, 2005 at 04:36 AM | Comments (10)

I spend half my time trying to identify what performance systems are doing by reproducing their behaviour in a performance testbed. It isn't always successful - I'd like to get profile information directly from the production systems, but even low overhead profilers can't get certain types of information in a low enough overhead way (I've tried, believe me I've tried).

One piece of info that is really useful to know is how many of each type of object has been created and has been GC'ed by the JVM. That information isn't available from the JVM, except if you use a profiler (with the honorable exception of JRockit which I think will give you this info in a low overhead way).

But all it takes is two instance variables added to each class object: countCreated and countGCed. And then the JVM just needs to increment each counter for each class when an object is created or GCed. That must surely be a neglible overhead added to the cost of object creation and garbage collection.

This is really the biggest bang for your buck I can think of to add to the JVM for improved monitoring of the system. With that information, so many things become possible, including automatic detection of memory leaks, identification of what may be causing high GC loads, etc.

Another in the would be nice to have category.


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • Rather than adding this to the JVM, wouldn't it be easier to make bytecode changes in compiled software?
    Suppose you get into contact with a customer using an interesting setup, you could send them an executable that weaves your addition into their compiled code. It doesn't matter whether it's their own code or some stuff they bought. The code could generate a report when the JVM is sent a certain signal.

    Posted by: bvankuik on May 25, 2005 at 05:03 AM

  • With JRockit you can do:

    jrcmd print_object_summary

    to get a histogram of all objects on the heap as well as the changes over time.

    Counting the number of objects that are GCed will lead to quite some overhead. Normally the JVM does not look at those objects. It marks all live objects as live and then just "frees" the rest of the memory without looking at the contents. Iterating over those objects during the GC would cost something.

    Regards,
    /Staffan, JRockit Staff

    Posted by: sla on May 25, 2005 at 05:50 AM

  • One of the problems is that with the exception of the slow path for finalisable objects, this information is generally not held for most objects. The reasoning is that the garbage collector basically just nukes the block of unused memory - it doesn't actually look at what's in there.

    So, without changes to most VMs I can't actually see this happening.

    Posted by: crnflke on May 25, 2005 at 07:14 AM

  • yes, I currently get created objects by bytecode injection or compile hacks depending on what I'm after. Of course you are right about the GC just blatting space - but it still does a mark so at least there is info about live objects. I wonder if that could be used instead.

    Posted by: jacksjpt on May 25, 2005 at 08:50 AM

  • I'm not willing to give up 8 bytes per object. That changes the object overhead from 16 bytes to 24.

    Posted by: keithkml on May 25, 2005 at 09:13 AM

  • it's 8 bytes per class, not per object

    Posted by: jacksjpt on May 25, 2005 at 09:37 AM

  • yes, there are going to be overheads with doing this, but it wouldn't hurt to at least allow the option of tracking collected objects.

    Posted by: goron on May 25, 2005 at 11:25 AM

  • There would be a significant overhead, and very little benefit.

    As far as I'm aware, the garbage-collection routines used to collect the young generation do not go through and free every object individually. They copy all the living objects into a safe area, and then nuke the remainder in one big block. This is how they manage to be so efficient. Adding these counts to objects would mean every object would need to be collected individually, and advanced GC techniques like this just wouldn't work. So you're not just making the app less efficient, you're totally altering the performance profile of the application, making any other measurements you would take useless.

    (This is also one reason that finalize() should be avoided if you can help it - requiring objects to be collected individually exempts them from taking part in all but the most inefficient (i.e. mark and sweep) GC algorithms.)

    You're far better off using a real profiler. Some can take rudimentary statistics with very little overhead.

    Posted by: carlfish on May 25, 2005 at 04:20 PM

  • Hmm, it seems to me that you could still do it efficiently. The JVM would track the number of live young generation objects per class. Than, as it copies each live young generation object on GC, it tallies up how many it copied. The number nuked is the remainder.

    On each new:
    - increment live object count

    On each GC:
    - tally live objects copied
    - nuked = old live objects - copied live objects
    - live object count = live objects copied

    Posted by: rharwood on May 26, 2005 at 03:40 AM

  • Wouldn't countCreated have to be synchronized between threads? So parallel object creaiton would be slower. With the amount of objects being created and destroyed in current app servers, this might become a significant overhead.

    Posted by: nielsull on May 26, 2005 at 05:21 AM





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds