Detect your Memory Leaks by counting Surviving Generations: Size matters!

The sunshine motivates me to run more these days. Just back from a beautiful run in Englischer Garten I am still sweating but I am also inspired by Rene’s article about JRockit that I read last night. It’s a very detailed article and well done – I tempted to write ‘as good as usual’ but I do understand how much work it is!

Java Memory Leaks

Most likely there is no training I do on behalf of Oracle without the subject “memory leaks”. So while still cooling down from my run, let me add a few points about memory leaks.

Size matters. At the end it is all about size! Wasting 20 bytes due to a mem leak is bad. Yet 20 bytes don’t affect your system. I bet you will neither notice nor detect it.

Wasting 20 bytes in a loop that runs a million times makes you probably notice the leak. Running the same loop with the leak 10 million times might crash your appserver.

Fast growth is not the issue. Slow growth is bad enough. Imagine you lose 20 bytes every minute. It’s a bit like a slow puncture tyre which constantly loses a bit of air. At the very end you sitting there with a flat tyre (Let me assume you life in a country with a mild climate and friendly people who will assist you to get the tyre changed quickly) . The same happens with your WebLogic heap. It’s not a lot of memory that you lose per time but it is the total size of the memory that is wasted over time. At the end your server will fail after three weeks (and WebLogic nodemanager restarts it for you πŸ™‚ ).

 

Don’t get me wrong. I am a big fan of JRockit, the team behind JRockit and its superb tools. Yet for a long time I wondered why JRockit’s memory leak tools still tries to detect “growth”.

Often I like to demo a 20 line Java program with 2 methods (mine is derived from the IBM page here, so you can get an idea). One method is consuming a lot of memory. The other one is losing 20 bytes every now and then. Of course the memory leak is within the second method, but JRockit tools detects the first method (which just happens to be mem intensive but correct).

Good news is: there is a better approach! It’s the kind of tools I love to explain in my workshops. Now it’s within the Oracle eco-system anyway but I used to spread the word long before.

Visual VM / Netbeans

VisualVM comes with your Sun JDK6 for free, originates from Netbeans, look for jvisualvm in JAVA_HOME/bin. It incorporates a memory profiler that uses a metric called “surviving generations” (or short “generations”). So what is a surviving generation?

Surviving generations:

The number of different ages for all objects allocated on the JVM heap since the profiling session started.

Age of object:

The age of the object is the number of garbage collections the object has survived.

 

Now the surviving generation metric is as good as it gets IMHO. A high number of SG tells that there isΒ  a high number of objects created which are never garbage collected (which is the definition of a memory leak, isn’t it?).

VisualVM displays the surviving generations metric, so it is easy to hunt them down.

 

 

To conclude:

  • Does it detect the slowly growing memory leak in the example above? Yes, it does!
  • VisualVM is only part of the Sun JDK, not of JRockit. Since we are all one happy family now I expect it survives the merging of both JDKs (Oracle is doing pretty well with these descisions usually. Hello Oracle …). Just in case it doesn’t survive I will keep posting references to this blog entry :).
  • Read more about JDK, WebLogic and monitoring (also the most important non-Oracle monitoring solutions) in my Oracle Middleware book.
  • I am regularly running a customized high-end Tuning, Sizing and Monitoring WebLogic workshop myself (preferably in Munich or Sydney). Drop me an email if you are interested.
  • I am off for a shower and the second coffee of the day. Enjoy the sunshine!

A live update on this from Oracle Open World 2011 as of Oct 3rd 2011. I just spoke to the tech lead of JRockit, Marcus Hirt, asked him about the support of surviving generations in the Jrockit Mission Control tooling for the merged JDK 7. His answer (with a very sympathic grin in his face) was: “Stay tuned…”.

 


Comments

  1. Thanks Frank,

    I got a good understanding of surviving generation. This was such an important parameter that i was missing. But I am yet to find some way of pin point an object’s reference in the code.
    I mean, i still need to get some idea of visual-vm if it would tell me the exact object and the location in my source code where it’s used.

    Had a good starting point anyway.

    Thanks,
    Enjoy your coffee πŸ™‚

    • Hello Jawad,

      thanks for your reply. I am travelling in APAC and had to set up my wireless broadband first. So it took me a while to reply.
      My intention with the memory leak post was to explain that there is a better approach available than just looking at growth rate for objects. But yes, there is also a way to get to the code:

      – In JVisualVM click on the “Profiler” tab, select the “Settings” check-box at the top right corner and enable “Record Allocation Stack Traces”:
      – Identify the classes with the high surviving generations count
      – Right click on the class with the highest number of surviving generation and select “Take snap-shot and show allocation stacktrace”.

      that’s it! That was pre-breakfast for me… Now I am off having a take-away soy latte while watching the surfers at the beach, best coffee ever πŸ™‚

      F.

  2. jossy jose says:

    Hi Frank,
    This topic is a good starter for me on visualVM and its gc plugin option. Thanks for the info.

    jossy.

  3. I updated this posting after I learned about the future JRockit tooling in respect with the merged JDK 7.

  4. Hi Frank,

    thanks for the article.

    Profiling my application for 3 days now, I made a strange observation:
    While the number surviving generations is constantly increasing (and now shows a value of 110), the heap space used stays at a constant level (140MB). Moreover, looking at the memory snap shot, one can see that the object with the highest number of generations is a HashMap with an age of only 8 generations.

    Currently I have no idea why I get such contradictory results.

    Tom

  5. Shadowknight says:

    Great article, I use net beans to profile my web application and I notice in the surving generation it save 1000 over 5 hrs.

    Now this is 100+ concurrent users , heap dump does not show any object with that generation highest is 10. It’s a shot in the dark but is this a leak or because my application creates so much objects . Object start in the gc 4% . After a day I get out of memory .

    Now is it that the application jvm needs to be allocate more memory. I don’t want to go over 2GB.

    Anyone with any heap usage for concurrent uses ?

  6. Hi,
    I wanted to know if VisualVM can be used in Eclipse or is it for NetBeans?

    Thanks

Trackbacks

  1. […] if you consider restarting you servers automatically because of out-of-memory problems, better read this article about “surviving generations”Β  to understand how to track down memory leaks and fix them. Anyway, you still want to use node […]

Speak Your Mind

*