Easy to Learn Java: Programming Articles, Examples and Tips

Start with Java in a few days with Java Lessons or Lectures

Home

Code Examples

Java Tools

More Java Tools!

Java Forum

All Java Tips

Books

Submit News
Search the site here...
Search...
 
Search the JavaFAQ.nu
1000 Java Tips ebook

1000 Java Tips - Click here for the high resolution copy!1000 Java Tips - Click here for the high resolution copy!

Java Screensaver, take it here

Free "1000 Java Tips" eBook is here! It is huge collection of big and small Java programming articles and tips. Please take your copy here.

Take your copy of free "Java Technology Screensaver"!.

Nulling variables and garbage collection

JavaFAQ Home » Story by Dr. Kabutz Go to all tips in Story by Dr. Kabutz


Bookmark and Share

The Java Specialists' Newsletter [Issue 060]

Author: Jack Shirazi

JDK version:

Category: Performance

If you are reading this, and have not subscribed, please consider doing it now by going to our subscribe page [http://www.javaspecialists.co.za/archive/subscribe.jsp]. You can subscribe either via email or RSS.


Welcome to the 60th edition of The Java(tm) Specialists' Newsletter sent to 5150 Java Specialists in 91 countries [http://www.javaspecialists.co.za/countries.jsp] . Thank you so much for your support this year, writing this newsletter, and especially reading your replies, has been an absolute pleasure. One thing that excites me is seeing famous names pop up on my reader list. One of these, Jack Shirazi [http://www.JavaPerformanceTuning.com] , a household name in Java performance circles and author of Java Performance Tuning, has been watching our newsletter for about a year and Jack and I have often had interesting discussions about the finer details of Java performance. This month Jack decided to interview me, you can gladly read the interview on his website [http://www.JavaPerformanceTuning.com/news/interview024.shtml] if you would like to.

Today Jack sent me an article for our newsletter, and I am honoured to publish it. Thanks Jack for this excellent article, we all really appreciate the time and effort you took in writing it for us.

After mentioning in my last newsletter how fantastic South Africa is, I have seen a dramatic strengthening of our currency. Ours is the best performing currency against the US$ in the last 12 months. I have come to the conclusion that someone on my mailing list has so much money that they can influence the economy of our country Wink

Enough of my musing, over to Jack Shirazi:

Jack Shirazi: Nulling variables and garbage collection

At JavaPerformanceTuning.com [http://www.JavaPerformanceTuning.com] , we have a monthly newsletter [http://www.JavaPerformanceTuning.com/newsletter.shtml] which includes a roundup of recent performance related discussions from various discussion groups. (We also have many more columns, covering almost all recent Java performance related activity, including interviews - last month we interviewed [http://www.JavaPerformanceTuning.com/news/interview024.shtml] none other than our excellent host, Heinz). The discussions we report are quite interesting, and sometimes a really fascinating one pops up.

One such discussion at Javagaming.org [http://www.Javagaming.org] considered whether setting variables to null helps garbage collection in any significant way. After a little inconclusive discussion, a Sun engineer jumped in with a really interesting example (Javagaming.org is a Sun owned discussion board, run by a couple of Sun engineers, and other Sun engineers sometimes lurk around).

This engineer pointed out that if Eden was full, and an object was about to be created, then if sufficient space could be freed in Eden, the object could be created there with no more work. But if sufficient space could NOT be freed, then existing objects in Eden had to be promoted to old space before the new object could be created. It could be that the application was finished with an object, but it had not yet gone out of scope, so could not be immediately garbage collected. Explicitly nulling the variable referencing that object would make a difference.

For those of you not up to spec on HotSpot GC, the heap is divided into several spaces: Eden and two survivor spaces (the three spaces collectively make up the young generation space) and an old generation space. Objects are created in Eden, and most objects die there and are reclaimed quickly. The two survivor spaces are for copying live objects so that young objects can remain in the young generation space for a time. If objects get too old, or young generation space gets full up, objects get promoted to the old generation space. If you need more detail, try these two URLs: Java World [http://www.javaworld.com/javaworld/jw-01-2002/jw-0111-hotspotgc.html] and Sun Microsystems [http://java.sun.com/docs/hotspot/gc] .

This being a gaming discussion board, the code example the engineer gave was relevant to animation, and a variation of his example follows here.

import java.awt.Image;
import java.awt.image.BufferedImage;

public class ImageGarbage1 {
  private static Image img;    //IMPORTANT 1
  public static void main(String args[]) {
    // Get one numerical argument which specifies size of image
    int imageSize = Integer.parseInt(args[0]);
    long startTime = System.currentTimeMillis();
    int imgIndex = 0;
    long loopIndex = 0;
    while (true) {
      //img = null;   //IMPORTANT 2
      // Create an image object
      img = new BufferedImage(imageSize, imageSize, 
        BufferedImage.TYPE_INT_RGB);
      long endTime = System.currentTimeMillis();
      ++loopIndex;
      // We print stats for every two seconds
      if (endTime - startTime >= 2000) {
        // Images created and disposed if per second
        long ips = (loopIndex / ((endTime - startTime) / 1000));
        System.out.println("IPS = " + ips);
        startTime = endTime;
        loopIndex = 0;
      }
    }
  }
}

Basically, this class repeatedly creates and discards images, measuring the rate of object creation, and printing that rate every couple of seconds. A single command line argument allows the size of the object to be specified.

On my desktop, I get the following results on running this:

COMMAND: java -version
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)

COMMAND: java ImageGarbage1 361
IPS = 14
IPS = 18
IPS = 19
IPS = 19

Your machines are probably a darn sight more powerful than my old desktop [hk: goodness me, even my 2 year old notebook is faster ;-], so I'm sure you'll get larger numbers. You need to control-C the process to stop it, otherwise it runs forever. Now let's look at what happens if I uncomment the line labelled "IMPORTANT 2", which simply adds a null assignment to the static variable before creating the image object:

COMMAND: java ImageGarbage2 361
IPS = 116
IPS = 160
IPS = 164
IPS = 165
IPS = 151

Yes, that's right, the null assignment made the test run an order of magnitude faster! Well I guess that's a pretty definitive answer to the question of whether nulling variables makes a difference. What is happening in the first test (ImageGarbage1) is that the image is created in Eden, and when the next image is created, the first image is still hard referenced by the application, so the GC has to promote the object to the old generation to make space for the new object. In the second test (ImageGarbage2), the inserted null reference means that the existing image in Eden is not referenced by the application, and can be discarded.

However, before you go off changing your coding style, I should point out that this is a specially constructed case. The image size was carefully chosen to fill Eden. Look what happens when we increase the image size slightly, even with the null assignment:

 
COMMAND: java ImageGarbage2 362
IPS = 13
IPS = 18
IPS = 18
IPS = 19

In this last test, the image is too big to fit into the young generation, and gets created directly in the old generation each time. Which means that a full mark-sweep GC of the old generation is needed to reclaim the space, rather than the much faster copying GC of the young generation. And if we choose a much smaller size, so that several images fit into Eden, then each subsequent image assignment releases the reference to the previous image, so allowing them all to be collected in Eden:

 
COMMAND: java ImageGarbage1 100
IPS = 759
IPS = 1487
IPS = 1490
IPS = 1490

COMMAND: java ImageGarbage2 100
IPS = 810
IPS = 1611
IPS = 1621
IPS = 1613

Let's make one more change. I'll go back to the original version of the test, with the null assignment commented out. But this time I'll change the static variable definition (the line labelled "IMPORTANT 1") into a local variable in the main() method. Now look what happens when I run the test with the image just fitting into Eden:

 
COMMAND: java ImageGarbage3 361
IPS = 113
IPS = 157
IPS = 165
IPS = 166
IPS = 156

We get back to the same performance as the test with the null assignment, even though we are NOT making that null assignment this time. In this case, the compiler is intelligent enough to work out the scope of the image object, and has dereferenced it before the next assignment, so allowing it to be reclaimed before the next image is created.

Finally, putting together what we've seen, it's easy to work out that Eden's size was the real problem with the original test. So let's get back to that original case, and simply alter the size. Here I simply set the initial heap size larger than the default, which makes Eden proportionately larger:

 
COMMAND: java -Xms16M ImageGarbage1 361
IPS = 78
IPS = 129
IPS = 120
IPS = 131

And the same test with the slightly larger image, that previously had to be created in old generation space:

 
COMMAND: java -Xms16M ImageGarbage1 362
IPS = 73
IPS = 120
IPS = 121
IPS = 121

So there is no real need to change your coding style. Tuning the garbage collection is probably a more sensible solution. Does nulling variables improve garbage collection? Maybe, sometimes.

Jack Shirazi is the author of "Java Performance Tuning" (O'Reilly), and director of JavaPerformanceTuning.com. JavaPerformanceTuning.com lists three thousand performance tuning tips and publishes a monthly newsletter with all the latest Java performance news, tips, discussions, and more. See http://www.JavaPerformanceTuning.com/

--Jack Shirazi
jack@JavaPerformanceTuning.com [mailto:jack@JavaPerformanceTuning.com]
http://www.JavaPerformanceTuning.com [http://www.JavaPerformanceTuning.com]


Copyright 2000-2005 Maximum Solutions, South Africa

Reprint Rights. Copyright subsists in all the material included in this email, but you may freely share the entire email with anyone you feel may be interested, and you may reprint excerpts both online and offline provided that you acknowledge the source as follows: This material from The Java(tm) Specialists' Newsletter by Maximum Solutions (South Africa). Please contact Maximum Solutions [http://www.javaspecialists.co.za] for more information.

Java and Sun are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. Maximum Solutions is independent of Sun Microsystems, Inc.

 Printer Friendly Page  Printer Friendly Page
 Send to a Friend  Send to a Friend

.. Bookmark and Share

Search here again if you need more info!
Custom Search



Home Code Examples Java Forum All Java Tips Books Submit News, Code... Search... Offshore Software Tech Doodling

RSS feed Java FAQ RSS feed Java FAQ News     

    RSS feed Java Forums RSS feed Java Forums

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest 1999-2006 by Java FAQs Daily Tips.

Interactive software released under GNU GPL, Code Credits, Privacy Policy