Java automatically calls garbage collector, then why we need manual calls for garbage collection? When should use System.gc()
问题:
回答1:
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.
(There can also be legitimate reasons to call System.gc()
in unit tests, and during system debugging.)
回答2:
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.
回答3:
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.
回答4:
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.
回答5:
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.
回答6:
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.
- Calling System.gc(); explicitly
- Bad practise - Calling System.gc();
- System.gc(); in java
PS : Btw, you should seriously take the extra effort to go through similar StackOverflow questions before posting about your doubts.
回答7:
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.