When I run the below mentioned code using NetBeans, the allocated heap size graph resembles a sawtooth shape. I am attaching the screen capture from JVisualVM which shows the heap allocation graph in with a sawtooth shape. The program is a simple infinite loop printing "Hello, World!" into the console.
public class HelloWorld {
public static void main(String a[]){
while(true) {
System.out.println("Hello, World!");
}
}
}
Can anyone explain the reason behind the shape of the graph of used heap?
PS: This happens even if I run it without using NetBeans, so it is most likely not related to NetBeans...
The sawtooth pattern in the heap usage can be explained by the fact that several local variables are created during the invocation of the System.out.println
invocation. Most notably in the Oracle/Sun JRE, several HeapCharBuffer
instances are created in the young generation, as noted in the following snapshot obtained using the memory profiler of VisualVM:
The interesting bit is in the number of live objects that are present on the heap. The sawtooth pattern results from the young-gen garbage collection cycle that occurs when the eden space fills up; since there is no heavy computational activity performed in the program, the JVM is able to execute several iterations of the loop, resulting in the eden space (of 4MB is in size) filling up. The succeeding young-gen collection cycle then clears out most of the garbage; it is almost always the whole of the eden space, unless the objects are still in use, as indicated by the following gc trace obtained from VisualVM:
The behavior of the sawtooth pattern can thus be explained by a series of object allocations in rapid succession that fill up the eden space, triggering a young gen garbage collection cycle; this process repeats cyclically with no delays as the underlying JVM process is not preempted by another process, and the main thread within the JVM that is responsible for the object allocations is also not preempted by another thread.
Any process allocating objects at regular rate will result in a steady increase in heap memory consumption, followed by instantaneous drops when the garbage collector collects the no longer used objects, resulting in that sawtooth shape.
In case you wonder why your java process keeps allocation memory while writing to System.out
, keep in mind that other threads (for instance the one feeding the current memory statistics to JVisualVM) may be the ones allocating the memory.
There's lots of places it could be coming from, and it's likely implementation dependent. At least the following are possible (but are all merely speculation)
somewhere in the stack of streams underneath System.out.println there is a byte array allocation (given that one of the basic methods of an output stream is write(bytes []b, int off, int len))
it's overhead used by the monitoring software you're using (I've not used it)
it's overhead in the netbeans VM where it ends up showing the output
Actually jVisualVM causing additional object allocation. jVisualVM and jconsole are using Java Management Extensions. Attaching to running application and requesting JVM metrics causing that additional objects are being created.
You can verify this by adding to your program call to
Runtime.getRuntime().freeMemory()
which reports free memory in JVM heap. It will show [almost] no memory change by running your code, but as soon as you connect jVisualVM to your program you'll see memory usage increase.