Getting started with garbage-collection
Garbage Collection (GC) is a way of automatically reclaiming memory that is occupied by objects that are no longer needed by a program. This is in contrast with manual memory management where the programmer explicitly specifies which objects should be deallocated and returned to memory. Good GC-strategies can be more efficient than manual memory management, but it may depend on the type of software.
The main advantages of garbage collection are:
- It frees the programmer from having to do doing manual memory management.
- It avoids certain difficult-to-find bugs that may arise from manual memory management (e.g. dangling pointers, double freeing, certain types of memory leaks).
- Languages that use garbage collection are usually less complex.
The main disadvantages are:
- Garbage collection has some overhead compared to manual memory management.
- It can potentially impact performance, especially when garbage collection is triggered at undesirable moments.
- It is indeterministic, the programmer doesn't know when garbage collection is done and if objects are freed or not.
Garbage collection strategies differ but many use a (variation of) the mark-and-sweep approach. In the mark phase all accessible objects are found and marked. In the sweep phase the heap is scanned for inaccessible and unmarked objects which are then cleaned up. Modern garbage collectors also use a generational approach where two or more object allocation regions (generations) are kept. The youngest generation contains the newest allocated objects and is cleaned more often. Objects that 'survive' for a certain timespan are promoted to an older generation.
Many languages with GC allow programmers to fine-tune it (see for example the Java 8 Virtual Machine Garbage Collection Tuning Guide or the .Net Garbage Collection documentation)
Enabling verbose gc logging in Java
Normally the jvm's garbage collection (gc) is transparent to the user (developer/engineer).
GC tuning is normally not required unless the user faces a memory leak or has an application that requires large amount of memory - both of which eventually lead to an out-of-memory exception which compels the user to look into the problem.
The first step is typically to increase the memory (either the heap or the perm-gen/meta-space depending on whether its due to load at runtime or the libary base of the application is large or there is a leak in the classloading or thread-handling mechanism). But whenever that is not feasible, the next step is to try to understand what is going wrong.
If one wants just the snapshot at a particular instant in time, then the
jstat utility that is part of the jdk would suffice.
However for a more detailed understanding, it is helpful to have a log containing the snapshot of the heap before and after each gc event. For that the user has to enable verbose gc logging by using the
-verbose:gc as part of the jvm startup parameters and including
For those who would like to pro-actively profile their application, there are also tools such as
jvisualvm that is also part of the jdk through which they can gain insight into the applications behaviour.
Below is a sample program, the gc configuration and the verbose-gc log output :
GC Options :
Below are few useful links on GC:
- An archived page explaining gc concepts (jdk7)
- G1 Collector Tutorial
- Useful VM Options
- JDK 5 - GC Ergonomics (concepts are still relevant)
- JDK 6 Tuning (concepts are still relevant)
Objects become eligible for garbage collection (GC) if they are no longer reachable by the main entry point(s) in a program. GC is usually not performed explicitly by the user, but to let the GC know an object is no longer needed a developer can:
Dereference / assign null
Use weak references
Most languages with GC allow you to create weak references to an object which do not count as a reference for the GC. If there are only weak references to an object and no strong (normal) references, then the object is eligible for GC.
Note that after this code it is dangerous to use the target of the weak reference without checking if the object still exists. Beginner-programmers sometimes make the mistake of using code like this:
This can cause problems because GC may have been invoked after the null check and before the execution of doSomeAction. It's better to first create a (temporary) strong reference to the object like this: