views:

55

answers:

2

I always had a question about heap memory behaviour.

Profiling my app i get the above graph. Seems all fine. But what i don't understand why,at GC time, the heap grows a litle bit, even there is enough memory (red circle).

That means for a long running app that it will run out of heap space at some time ?

alt text

+4  A: 

Not necessarily. The garbage collector is free to use up to the maximum allocated heap in any way it sees fit. Extrapolating future GC behaviour based on current behaviour (but with different memory conditions) is in no way guaranteed to be accurate.

This does have the unfortunate side effect that it's very difficult to determine whether an OutOfMemoryError is going to happen unless it does. A legal (yet probably quite inefficient) garbage collector could simply do nothing until the memory ceiling was hit, then do a stop-the-world mark and sweep of the entire heap. With this implementation, you'd see your memory constantly increasing, and might be tempted to say that an OOME was imminent, but you just can't tell.

With such small heap sizes, the increase here is likely just due to bookkeeping/cache size alignment/etc. You're talking about less than 50KB or so looking at the resolution on the scale, so I shouldn't be worried.

If you do think there's a legitimate risk of OutOfMemoryErrors, the only way to show this is to put a stress test together and show that the application really does run out of heap space.

Andrzej Doyle
In addition to Andrzej statement, When the JVM has to allocate more heap space it can be slow/taxing on the system. If you have a comfortable level which you know your application will run on, then setting some start-up parameters you can prevent this growth. For the original case, you seem to get GC around the 18mb mark. The graph shows that you start with around 4mb of heap allocated and will work its way up around the 20mb mark. Just set the -Xms32mb and -Xmx32mb flags when your program starts. Now your JVM is free of having to allocate more heap for you.
Sean
+3  A: 

The HotSpot garbage collectors decide to increase the total heap size immediately after a full GC has completed if the ratio of free space to total heap size falls below a certain threshold. This ratio can be tuned using one of the many -XX options for the garbage collector(s).

Looking at the memory graph, you will see that the heap size increases occur at the "saw points"; i.e. the local maxima. Each of these correspond to running a full GC. If you look really carefully at the "points" where the heap gets expanded, you will see that in each case the amount of free space immediately following the full GC is a bit higher than the previous such "point".

I image that what is happening is that you application's memory usage is cyclical. If the GC runs at or near a high point of the cycle, it won't be able to free as much memory as if the GC runs at or near a low point. This variability may be enough to cause the GC to expand the heap.

(Another possibility is that your application has a slow memory leak.)

That means for a long running app that it will run out of heap space at some time ?

No. Assuming that your application's memory usage (i.e. the integral of space occupied by reachable objects) is cyclic, the heap size will approach a fixed high limit and never exceed it. Certainly OOME's are not inevitable.

Stephen C
Just curious, do you have any sources for "HotSpot garbage collectors decide to increase the total heap size immediately after a full GC has completed if the ratio of free space to total heap size falls below a certain threshold"? I'd like to read more about this.
matt b
@mattb -- The option is -XX:MinHeapFreeRatio, as documented by http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
Dilum Ranatunga