I have a complex java application running on a large dataset. The application performs reasonably fast but as time goes it seems to eat lots of memory and slow down. Is there a way to run the JVM garbage collector without re-starting the application?
-
4It will run automatically if resources become scarce. So either some resources are reclaimable and you should not need to do anything, or there aren't any in which case you need to modify your design... – assylias Feb 11 '13 at 12:00
-
1What evidence is there that memory use is causing your performance problem? I'm not saying that it is NOT your problem, but if what you want to do is speed up your application, you should make sure you are looking in the right place for improvements. You could waste a lot of time TRYING to improve performance if you do not really know where it's being lost in the first place. The phrases "as time goes" (2 minutes, 3 hours, 4 days?) and "seems to eat lots of memory" (are you finding bits of it on the floor?) make me wonder whether the root cause has been sufficiently determined. – arcy Feb 11 '13 at 12:15
-
1Funny that this question is asked by a user called 'DotNet' (-: – Adriaan Koster Feb 11 '13 at 14:50
8 Answers
No, You cant force garbage collection.
Even using
System.gc();
You can just make a request for garbage collection but it depends on JVM to do it or not.
Also Garbage collector are smart enough to collect unused memory when required so instead of forcing garbage collection you should check if you are handling objects in a wrong way.
If you are handling objects in a wrong way (like keeping reference to unnecessary objects) there is hardly anything JVM can do to free the memory.
From Doc
Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.
Open Bug regarding System.gc()
documentation
The documentation for System.gc() is extremely misleading and fails to make reference to the recommended practise of never calling System.gc().
The choice of language leaves it unclear what the behaviour would be when System.gc() is called and what external factors will influence the behaviour.
Few useful link to visit when you think you should force JVM to free up some memory
1. How does garbage collection work
2. When does System.gc() do anything
3. Why is it bad practice to call System.gc()?
All says
1. You dont have control over GC in Java even System.gc()
dont guarantee it.
2. Also its bad practise as forcing it may have adverse effect on performance.
3. Revisit your design and let JVM do his work :)
-
Just to extend my knowledge, could you please submit a link to a source that explain cases where the GC is not executed when calling `System.gc()` (except when it has been explicitely disabled)? – Neet Feb 11 '13 at 12:08
-
Yeah, and the first line in the API doc says: 'Runs the garbage collector.' – Neet Feb 11 '13 at 12:13
-
@Neet: I have updated my answer, If you read further it says suggests and best possible efforts. – Ajinkya Feb 11 '13 at 12:13
-
It runs the garbage collector, it just does make no definite assumptions about the outcome (that's the 'best effort' part ... you can never tell how much memory can be made available), but GC is executed. And I did not encounter any JVM that does not perform a GC on `System.gc()`. – Neet Feb 11 '13 at 12:13
-
@Neet: The doc says calling `gc()` means just a suggestion to JVM and rest of the things depends on JVM. – Ajinkya Feb 11 '13 at 12:16
-
So, finally found a link that is a bit clearer about this ... and suggests to me that the API doc of `System.gc()` should be edited: http://docs.oracle.com/cd/E13222_01/wls/docs81/perform/JVMTuning.html#1119353 ... so here's my +1 :) – Neet Feb 11 '13 at 12:21
-
@Neet: Thanks!. I have found a bug which also says that docs for `gc()` is misleading, I have added it to my answer. – Ajinkya Feb 11 '13 at 12:22
-
but the bug does again only talk about 'JVM configurations' not implementations. *sigh* They should finally settle down on one term, either 'configuration' or 'implementation'. – Neet Feb 11 '13 at 12:25
-
@Neet - it could be *either* 'configuration' or 'implementation'. The javadoc for the `System.gc()` method is a *specification* that allows a variety of approaches. I'm pretty sure that is is deliberate. – Stephen C Feb 11 '13 at 15:27
you should not relay on System.gc()
- if you feel like you need to force GC to run it usually means that there is something wrong with your code/design. GC will run and clear your unused objects if they are ready to be created - please verify your design and think more about memory management, look as well for loops in object references.

- 140
- 7
The
System.gc()
call in java, suggest to the vm to run garbage collection. Though it doesn't guarantee that it will actually do it. Nevertheless the best solution you have. As mentioned in other responses jvisualvm utility (present in JDK since JDK 6 update 7), provides a garbage functionality as well.
EDIT:
your question open my appetite for the topic and I came across this resource:

- 5,001
- 4
- 34
- 49
The application performs reasonably fast but as time goes it seems to eat lots of memory and slow down.
These are a classic symptoms of a Java memory. It is likely that somewhere in your application there is a data structure that just keeps growing. As the heap gets close to full, the JVM spends an increasing proportion of its time running the GC in a (futile) attempt to claw back some space.
Forcing the GC won't fix this, because the GC can't collect the data structure. In fact forcing the GC to run just makes the application slower.
The cure for the problem is to find what is causing the memory leak, and fix it.

- 698,415
- 94
- 811
- 1,216
-
This is the 2nd question like this in a few hours .... http://stackoverflow.com/questions/14810303/java-heap-size-increasing/14810443#14810443 – Stephen C Feb 11 '13 at 15:36
-
Thanks Stephen. Yes, I'm debugging the code and found such data structures. – DotNet Feb 11 '13 at 15:41
Performance gain/drop depends how often you need garbage collection and how much memory your jvm has and how much your program needs.
There is no certainity(its just a hint to the interpreter) of garbage collection when you call System.gc() but at least has a probability. With enough number of calls, you can achieve some statistically derived performance multiplier for only your system setup.
Below graph shows an example program's executions' consumptions and jvm was given only 1GB(no gc),1GB(gc),3GB(gc),3GB(no gc) heaps respectively to each trials.
At first, when jvm was given only 1GB memory while program needed 3.75GB, it took more than 50 seconds for the producer thread pool to complete their job because having less garbage management lead to poor object creation rate.
Second example is about %40 faster because System.gc() is called between each production of 150MB object data.
At third example, jvm is given 3GB memory space while keeping System.gc() on. More memory has given more performance as expected.
But when I turned System.gc() off at the same 3GB environment, it was faster!
Even if we cannot force it, we can have some percentage gain or drain of performance trying System.g() if we try long enough. At least on my windows-7 64 bit operating system with latest jvm .

- 11,469
- 4
- 45
- 97
Garbage collector runs automatically. You can't force the garbage collector.

- 1,115
- 6
- 22
- 33
I do not suggest that you do that but to force the garbage collector to run from within your java code you can just use all the available memory, this works because the garbage collector will run before the JVM throws OutOfMemoryError...
try {
List<Object> tempList = new ArrayList<Object>();
while (true) {
tempList.add(new byte[Integer.MAX_VALUE]);
}
} catch (OutOfMemoryError OME) {
// OK, Garbage Collector will have run now...
}

- 12,614
- 4
- 38
- 46
-
http://docs.oracle.com/javase/6/docs/api/java/lang/OutOfMemoryError.html It says `(thrown when) no more memory could be made available by the garbage collector` – Ajinkya Feb 11 '13 at 12:34
My answer is going to be different than the others but it will lead to the same point. Explain: YES it is possible to force the garbage collector with two methods used at the same time and in the same order this are:
System.gc ();
System.runFinalization ();
this two methods call will force the garbage collector to execute the finalise() method of any unreachable object and free the memory. however the performance of the software will down considerable this is because garbage runs in his own thread and to that one is not way to controlled and depending of the algorithm used by the garbage collector could lead to a unnecessary over processing, It is better if you check your code because it must be broken to you need use the garbage collector to work in a good manner.
NOTE: just to keep on mind this will works only if in the finalize method is not a reassignment of the object, if this happens the object will keep alive an it will have a resurrection which is technically possible.

- 598
- 6
- 13