I'm exploring memory usage in Java to understand why my program leaks memory. After stripping off code in my main while loop, I still get an increase of memory usage over time. Pondering the memory usage of an empty program:
class Nothing { public static void main(String[] args) { while(true); } }
I still saw an increase of memory:
So my question is: Why is there still a saw tooth pattern? Why when the GC runs does it not save all the memory (each time the gc runs (the valleys) the used memory increases by 10-20Kb (compared to the previous valley))?
EDIT:
java version "1.6.0_29"
Java(TM) SE Runtime Environment (build 1.6.0_29-b11)
Java HotSpot(TM) Client VM (build 20.4-b02, mixed mode, sharing)
OS: Windows 7 Enterprise-32 bit
This is due to the nature of garbage collection technology used in Java. Freeing memory in such systems is delayed until some threshold reached, or out of memory happens, or some time passes.
To avoid wasting time optimizing wrong parts of the code, you need to obtain a JVM heap dump and analyze it with an appropriate tool. If you enjoyed this article and want to learn more about Java Collections, check out this collection of tutorials and articles on all things Java Collections.
In general, a Java memory leak happens when an application unintentionally (due to logical errors in code) holds on to object references that are no longer required. These unintentional object references prevent the built-in Java garbage collection mechanism from freeing up the memory consumed by these objects.
Why is there still a saw tooth pattern?
If I'm not mistaken, part of the reason for this is that the monitor itself is forcing the application to create temporary objects that contain information about the state of garbage-collection and memory usage.
Why when the GC runs does it not save all the memory (each time the gc runs (the valleys) the used memory increases by 10-20Kb (compared to the previous valley))?
I believe the monitor does not instantly see the amount of used memory after garbage-collection, but rather, must poll frequently to see memory usage. Therefore, the perceived "valley" is necessarily somewhat higher than the true valley. I would guess that the perceived increase in memory usage at the valleys is just a random artifact of this discrepancy, and would be neutralized over time. (That is, I don't think that there's actually 10-20 KB of memory leak occurring in each cycle.)
This is an artifact by the profiler, without the profiler there will be no allocations. Different profilers produce different artifacts, depending on how they record data. Below you see what profiling Nothing
JProfiler will look like:
Much less of a sawtooth pattern. However, there is also a minuscule memory consumption:
which is due to the fact the profiling agent polls the java.lang.management.MemoryUsage
JMX bean. Eventually this consumption will also trigger a garbage collection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With