I was reading up on java performance tuning and ran into this.
When we run
public class test {
public static void main(String a[]){
for(int i=0;i<1000000;i++){
for(int j=0;j<100000;j++){
Double d = new Double(1.0);
}
}
}
}
JVisualVM shows a flat for memory consumption graph:

But when we run the below code,
public class test {
public static void main(String a[]){
for(int i=0;i<1000000;i++){
for(int j=0;j<100000;j++){
}
}
}
}
JVisualVM renders a sawtooth:

Why is this happening? How and why gc triggering limit is changed for both the cases?
Regarding your v1 for loops, your local variable, once it has exited its scope, it will be marked for GC as free to be collected, so every once in a while the GC will kick in and collect that memory.
For your v2 for loops, those empty loops won't be 'optimized away' by the compiler**, only after multiple calls, because the
JIT triggers AFTER a certain piece of code has been executed many times [1]
Regarding your saw tooth pattern, ruakh has a very nice explanation about it [2] :
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.
** It is possible that they may never be removed because those empty loops are well known as being used as a waiting mechanism.*
[1] Java: how much time does an empty loop use? - Simone Gianni's answer
[2] Why does an empty Java program consume memory?
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