2

This is related to my question Java Excel POI stops after multiple execution by quartz.

My program stops unexpectedly after a few iterations. I tried profiling and found that I was consuming a lot of heap memory per iteration (And a memory leak somewhere.. havn't found the bugger yet). So, as a temporary solution, I tried inserting System.gc(); at the end of each complete execution of the program (kindly read the linked question for a brief description of the program). I was not expecting much, maybe a few more heap space available after each iteration. But, it appears that the program uses less heap memory when I inserted System.gc();.

enter image description here

The top graph shows the program running with the System.gc(); while the bottom graph is the one without. As you can see the top graph shows that I'm only using less than a 100mb after 4 iteratioins of the program while the bottom graph shows over 100mb in usage for the same amount of iterations. Can anyone clarify how and why System.gc(); causes this effect in my heap? If there are any disadvantages if I were to use this in my program? Or I'm completely hopless in programming and take up photography instead?

Note that I inserted GC at the end of each program iteration. So I assume that heap usage must be the same as without the GC inserted until it meets the the System.gc(); command

Thanks!

Community
  • 1
  • 1
ides
  • 369
  • 6
  • 16

3 Answers3

1

As per the Java specs, calling gc() does not guarantee that it will run, you only hint to the JVM that you need it to run, so the result is unreliable (You should avoid calling gc() at not matter what). But, in your case here and since the heap is reaching critical limits incrementally, that's why perhaps your hints are being executed.

GC usually runs based on specific algorithms to prevent the heap from being exhausted and when it fails to reclaim the much needed space while having no more heap for you app to survive, you'll face the OutOfMemoryException.

While the GC is running, your application will experience some pauses as a result of its activities, so you won't really want it to run more often!

Your best bet is to solve the leak and practice better memory management for a healthy runtime experience.

user207421
  • 305,947
  • 44
  • 307
  • 483
Waleed Almadanat
  • 1,027
  • 10
  • 24
1

Can anyone clarify how and why System.gc(); causes this effect in my heap?

System.gc is kind of a request service for the Garbage Collector to Run. Note that I have used request and not trigger in my statement. GC based upon the heap state might/not carry on collection.

If there are any disadvantages if I were to use this in my program?

From experience, GC works best when left alone. In your example you shouldn't worry or use System.gc. Because GC will run when it is best to run and manually requesting it might reduce the performance. Even though only a small difference, you can observe that "time spent on gc" is better in the below graph than the first one.

As per memory, both the graphs are OK. Seems like your max heap is a bit high. Hence GC did-not run it in second graph. If it was really required, it would have ran it.

Jatin
  • 31,116
  • 15
  • 98
  • 163
  • 1
    @ides To complement Jatin's answer, you have to remember that the used heap includes the garbage that can be collected. As long as you're below the level which will trigger the GC (which depends on the algorithm used), the heap keeps growing, and that's normal: the garbage collection itself has a cost, so you have to find a balance between the frequency and the latency it introduces. The first step to manage that is simply by adjusting `Xmx`. – Frank Pavageau Jan 02 '13 at 14:55
0

Using System.gc() shouldn't impact the heap size allocated to JVM. Heap size is dependent only on startup arguments we provide to our JVM. I will recommend you to run the same program 3-4 times and take average values with System.gc() and without.

Coming back to the problem of finding the memory leak; I will recommend to use JProfiler or other tools which would tell you exact memory footprint; and different objects in the heap.

Last but not the least; you are a reasonable programmer. No need of going for a photo shoot :)

Deepak Singhal
  • 10,568
  • 11
  • 59
  • 98
  • This is incorrect. There are several JVM arguments that let you control the heap size. You can control the size of the initial heap as well as the maximum size of the heap. By default, Java will not allocate the full heap space at startup but will enlarge the heap when needed. There is obviously no memory leak when the garbage collector is able to free the memory... – Mathias Schwarz Jan 02 '13 at 08:28
  • @MathiasSchwarz I agree with what you say. Even I mentioned that Heap size is dependent ONLY on JVM arguments where we can specify min & max heap size. – Deepak Singhal Jan 02 '13 at 08:30
  • Thanks for the response. I did profile the program a couple of times and the results are closely similar to the one I mentioned above. As for the heap size, I have it set to 512m. The difference is in the used heap and not the initial and maximum heap. I'm currently trying to look for the memory leak but I'm having a hard time finding it. It's like dandruff in the snow. – ides Jan 02 '13 at 08:46