Java automatically calls garbage collector, then why we need manual calls for garbage collection? When should use System.gc()
-
12In general, never.SLaks– SLaks2011年02月23日 03:50:13 +00:00Commented Feb 23, 2011 at 3:50
-
very similar to this postBala R– Bala R2011年02月23日 03:50:30 +00:00Commented Feb 23, 2011 at 3:50
7 Answers 7
Java automatically calls garbage collector, then why we need manual calls for garbage collection?
We don't need them. Indeed, in most circumstances calling System.gc() is harmful for application performance. See my answer to "Why is it a bad practice to call system gc" for a detailed explanation.
When should use System.gc()
If the application knows it is going into a phase where it has nothing else to do AND the user is unlikely to notice a garbage collection, then maybe it is OK call to System.gc() in an effort to stop the user experiencing GC pauses in the future.
The downsides include:
- Calling
System.gc()typically triggers a full GC which takes significantly longer than a GC of the 'new space'. - The user may actually care / notice. For example, if you call
System.gc()between "levels" in a game, you make loading the next level take longer. - By forcing the GC, you are causing the JVM to use extra CPU cycles, etc which may potentially interfere with other things that the user is doing on his machine. (Or drain the battery on a mobile device.)
(There can also be legitimate reasons to call System.gc() in unit tests, and during system debugging.)
Comments
There isn't a need to call for garbage collection explicitly and calling System.gc() is only a suggestion, the JVM can ignore your suggestion.
The only practical uses I can think of is
- During debugging, forcing a collection can expose a memory leak
- If the program goes through predictable cycles of intense computation followed by no computation (like a turn based game), during the no-computation period the CPU could be utilized for a suggested garbage collection to prevent jitter during the intense computation portions.
4 Comments
System.gc() is only a suggestion. But it does make sense in some situations.
Suppose you have class MyClass, and you're wondering how much memory does one instance take. What you can do is this (roughly speaking):
MyClass [] objects= new MyClass[100000];
System.gc();
long memoryNow = Runtime.getRuntime().freeMemory();
for (int i = 0; i < 100000; i ++) {
objects[i] = new MyClass();
}
System.gc();
long memoryLater = Runtime.getRuntime().freeMemory();
int objectSize = (int)((memoryLater - memoryNow) / 100000);
There are other similar cases I've found System.gc() to be useful.
Comments
One aspect not yet mentioned is that some types of objects may ask entities outside themselves to do things on their behalf (e.g. give them exclusive access to a non-fungible resource like a file), to the detriment of other entities. When a garbage-collection is performed, the system will not only free up memory that was formerly occupied by unreachable objects, but it will also call finalize on objects that it notices have been abandoned, thus allowing such objects to notify outside entities that their services are no longer required. It is entirely possible for a program to reach a state where there's plenty of memory, but a necessary resource is unavailable because an object has been granted exclusive access and has since been abandoned without releasing it. Forcing the garbage-collector to run in such a situation may sometimes free up the necessary resource.
10 Comments
finally blocks (or similar) to ensure that resources don't "leak".try/finally block [even though the JVM would]; (2) if the base-class constructor acquires a resource and a derived-class constructor throws, the resource will leak unless the throw occurred within a try/finally block. Note that...myThing = new Thing(); cannot be wrapped in a try-finally, so if any such declaration throws, whether or not it acquires resources, base-class resource leaks will be hard to avoid since no reference to the base-class object will exist. The only way I know to avoid resource leaks in such cases is by using ThreadLocal to keep track of resources which have been acquired but not yet been "handed off" to entities that have promised to close them.The garbage collector is always called by the JVM when there is not enough memory to allocate new objects into the heap. While calling the garbage collector, it follows the Stop the World norms and for this it calls the System.gc() method.
Also remember that the JVM also runs parallel gc threads to remove unused objects from memory . So everything and every minute JVM maintains heap memory and always tries to not overload it. So there is no any requirement to explicitly call System.gc() or Runtime.gc() method.
If you want more detail about this you can get here for the relevant information.
Comments
Garbage collection process is not under the user's control.So it makes no sense to call System.gc(); explicitly. It entirely depends on the JVM.
Few days back, I had asked exactly the same question : [Here].
In fact, many questions related to calling System.gc(); explicitly have been already asked and answered here. Calling System.gc(); explicitly is always considered as poor programming skill, although it won't do any harm.
Here are the few links that I you should go through it. It will definitely clarify your doubt.
PS : Btw, you should seriously take the extra effort to go through similar StackOverflow questions before posting about your doubts.
1 Comment
There is no need to call System.gc() or Runtime.getRuntime().gc(). The JVM internally controls garbage collection if it finds that it is running out of memory.