6

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:

enter image description here

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:

enter image description here

Why is this happening? How and why gc triggering limit is changed for both the cases?

buch11
  • 872
  • 3
  • 13
  • 29
  • 2
    I think empty loop take more processor. So GC didnt chance to run. – Siva Kumar Aug 20 '14 at 11:00
  • 2
    Which version of Java? What parameters? Second test with empty loop should work 0 seconds, because java is not so stupid to run empty loops. – Andremoniy Aug 20 '14 at 11:03
  • 1
    possible duplicate: http://stackoverflow.com/questions/8361902/why-does-an-empty-java-program-consume-memory –  Aug 20 '14 at 11:04
  • 1
    @Andremoniy - No. java can run empty loops (even after Escape Analysis was introduced i.e, after jdk6U23) – TheLostMind Aug 20 '14 at 11:04
  • @Andremoniy Empty loops can have a purpose see nafas answer below, so of course java should run it. – Duane Aug 20 '14 at 11:09
  • Do one thing. Run both testes *one after another* in the same method and by giving a warm-up run for each. *statistics* can somethimes be *misleading*. – TheLostMind Aug 20 '14 at 11:09
  • 1
    I must say, this is an excellent question to with a simple example prove just how important it is to not make -any- assumptions when doing performance tests. Can we have the source you were reading this in? Was it the Oracle performance tuning article or a book? – Gimby Aug 20 '14 at 11:13
  • Ok Ok, guys,but I can not reproduce this behaviour on Java 1.7.0.40 x64 on Windows 7. – Andremoniy Aug 20 '14 at 13:29
  • possible duplicate of [Java: how much time does an empty loop use?](http://stackoverflow.com/questions/7271147/java-how-much-time-does-an-empty-loop-use) – durron597 Aug 20 '14 at 14:09
  • The second diagram is not reproducible. Which platform do you run the test on? OS, JDK version? Do you connect VisualVM locally or remotely? – apangin Aug 20 '14 at 20:23

2 Answers2

2

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?

Community
  • 1
  • 1
Daniel
  • 1,861
  • 1
  • 15
  • 23
1

The reason is the optimization algorithm once the code is compiled. on the first case because you create a double every time without keeping a record of it.This would make the program use GC constantly. Thus the compiler optimize the code so less memory used. Empty loop is a special case, because many programmer use it to make a thread to wait. so compiler won't try to optimize that.

nafas
  • 5,283
  • 3
  • 29
  • 57
  • This is not true. HotSpot JIT is happy to optimize empty loops out when it can. C2 compiler (aka "server VM") can and does it. The second test case exits immediately on x64 JDK. But it seems that OP is running the test on C1 (aka "client VM") - this compiler is just not smart enough to remove an empty loop. – apangin Aug 20 '14 at 20:13
  • @apangin there are many different compilers. this is one of the optimization that "javac" uses. as the matter of fact it used to optimize empty loop as well, however they change it back due to some requests from gaming industry. (I don't know why but apparently some game producers use empty loop for waiting) – nafas Aug 20 '14 at 20:31