Card 06/ 09

GotchaDifficulty: Advanced1 min

System.gc() Is Only a Suggestion

A batch job asks for a collection after every file, and gets slower with the same memory graph.

System.gc() asks the JVM to run the garbage collector (the part of the JVM that frees memory no longer in use), and the JVM may ignore it. When it does comply it can pause the whole application, and it can never free an object that is still reachable (still connected, through some chain of references, to a variable the program is using), so it does not fix growing memory.

A batch job calls System.gc() between files to keep memory down. The graph of the heap, the memory holding every object, is unchanged and the job is measurably slower than it was:

java
for (Path file : files) {
    process(file);
    System.gc();
}

System.gc() is a request, and the specification says so: it suggests that the virtual machine spend effort on collection. Whether anything happens, when it happens and how much is collected are all decisions the collector keeps.

What the call does and does not do
DoesDoes not
Suggest a collectionGuarantee one runs
Sometimes trigger a full collection, which pauses the whole application of the applicationFree memory that is still reachable
Cost time, reliablyFix a leak

If memory is growing, the objects are reachable and no collector can take them. The call cannot help, because the thing it asks for already happens whenever it can. Find what is still holding them instead.