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