Sunday, March 11, 2012

Why does java wait so long to run the garbage collector?


I am building a Java web app, using the Play! Framework . I'm hosting it on playapps.net . I have been puzzling for a while over the provided graphs of memory consumption. Here is a sample:



Heap Memory



The graph comes from a period of consistent but nominal activity. I did nothing to trigger the falloff in memory, so I presume this occurred because the garbage collector ran as it has almost reached its allowable memory consumption.



My questions:



  • Is it fair for me to assume that my application does not have a memory leak, as it appears that all the memory is correctly reclaimed by the garbage collector when it does run?

  • (from the title) Why is java waiting until the last possible second to run the garbage collector? I am seeing significant performance degradation as the memory consumption grows to the top fourth of the graph.

  • If my assertions above are correct, then how can I go about fixing this issue? The other posts I have read on SO seem opposed to calls to System.gc() , ranging from neutral ("it's only a request to run GC, so the JVM may just ignore you") to outright opposed ("code that relies on System.gc() is fundamentally broken"). Or am I off base here, and I should be looking for defects in my own code that is causing this behavior and intermittent performance loss?



I apologize for the brain dump of questions; I've been debugging this issue for a while now, and would greatly appreciate any pointers.



UPDATE

I have opened a discussion on PlayApps.net pointing to this question and mentioning some of the points here; specifically @Affe's comment regarding the settings for a full GC being set very conservatively, and @G_H's comment about settings for the initial and max heap size.



Here's a link to the discussion , though you unfortunately need a playapps account to view it.



I will report the feedback here when I get it; thanks so much everyone for your answers, I've already learned a great deal from them!



Resolution

Playapps support, which is still great, didn't have many suggestions for me, their only thought being that if I was using the cache extensively this may be keeping objects alive longer than need be, but that isn't the case. I still learned a ton (woo hoo!), and I gave @Ryan Amos the green check as I took his suggestion of calling System.gc() every half day, which for now is working fine.



Thanks again for all the help, as always!

No comments:

Post a Comment