Garbage Collection in Java: Interview Questions and Answers
This page addresses frequently asked interview questions about garbage collection in Java, a crucial aspect of Java's automatic memory management.
Why is Garbage Collection Necessary in Java?
Unlike languages like C and C++, where developers manually manage memory, Java uses garbage collection (GC). GC automatically identifies and reclaims memory occupied by objects no longer in use. This simplifies development and reduces memory leaks.
Drawbacks of Garbage Collection
The primary drawback is that GC can pause application threads during the memory reclamation phase. These pauses, lasting from milliseconds to seconds, can impact application responsiveness, and GC cannot be precisely scheduled.
Java Heap Structure
The Java heap is a runtime data area shared by all threads. It's typically divided into three generations:
- Young Generation: Where newly created objects reside.
- Old Generation (Tenured Generation): Objects that survive multiple garbage collection cycles in the young generation are moved here.
- Permanent Generation (PermGen/Metaspace): Stores metadata about classes and methods (this area's handling changed significantly in Java versions after 7).
Learn more about the Java Heap structure
PermGen Space (and Metaspace)
PermGen space (Permanent Generation) in older JVMs stored metadata (information about classes and methods). In newer Java versions (8 and later), Metaspace replaces PermGen, and garbage collection still applies to this area.
Learn more about PermGen space and Metaspace
Minor, Major, and Full Garbage Collection
There's no strict definition, but generally:
- Minor GC: Garbage collection in the young generation (Eden space).
- Major GC: Garbage collection in the old generation.
- Full GC: Garbage collection across all generations (young and old).
Identifying GC Types in Logs
When GC logging is enabled (using -XX:PrintGCDetails
or -verbose:gc
), "GC" usually indicates minor GC, and "Full GC" indicates a major or full GC.
ParNew vs. DefNew Garbage Collectors
- ParNew: A multi-threaded garbage collector often used with concurrent mark-sweep collectors.
- DefNew: A single-threaded garbage collector typically used with the serial garbage collector.
finalize()
Method
The finalize()
method (a finalizer) is called by the garbage collector *before* an object is garbage collected. It provides a final opportunity for the object to release resources.
Forcing Garbage Collection
You cannot directly force garbage collection. Calling System.gc()
or Runtime.getRuntime().gc()
only *requests* a garbage collection; it's not guaranteed to run immediately.
Garbage Collection in PermGen/Metaspace
Yes, garbage collection happens in PermGen (older JVMs) and Metaspace (newer JVMs). A full garbage collection might be triggered if these areas reach their capacity limits.
When Objects Become Eligible for GC
An object becomes eligible for garbage collection when it's no longer reachable from any active part of your program (no references point to it). This typically happens when:
- A reference variable is set to
null
. - The object goes out of scope.
- There are no more live references to the object.
Mark-and-Sweep
Mark-and-sweep is a garbage collection algorithm. The "mark" phase identifies unreachable objects. The "sweep" phase reclaims the memory occupied by these objects.
Minor, Major, and Full GC (More Detail)
While not officially defined, Minor GC typically focuses on the Eden space (young generation), Major GC on the old generation, and Full GC on all generations.
Memory Leaks
A memory leak occurs when an application holds references to objects that are no longer needed, preventing the garbage collector from reclaiming their memory. This leads to increased memory consumption, potentially causing performance problems or crashes.
Triggering GC from Code
You can request garbage collection using System.gc()
, but it's not guaranteed to run immediately. It's generally best to rely on the JVM's automatic GC management.
GC and Memory Areas
Garbage collection primarily operates on the heap, not the stack.
Responsibilities of GC
The garbage collector's main role is to reclaim unused memory, improving memory efficiency. However, it doesn't guarantee sufficient memory for the program's execution.
Daemon Threads and GC
A daemon thread runs in the background and terminates when all non-daemon threads have finished. The garbage collector is a daemon thread.
Making Objects Eligible for GC
To make an object eligible for garbage collection:
- Set all references to the object to
null
. - Let the object go out of scope (it's no longer accessible).
- Create "islands of isolation" (objects only referencing each other with no outside references).
Advantages of Garbage Collection
Automatic garbage collection simplifies development, preventing memory leaks and freeing developers from manual memory management.
Purpose of Overriding finalize()
Override the finalize()
method to perform cleanup tasks (like closing files or releasing resources) before an object is garbage collected. It's called only once per object.
Garbage Collection and `finalize()` Calls
The garbage collector calls the `finalize()` method only once for each object.
GC Thread Type
The garbage collector runs as a background daemon thread.
Garbage Collection Pause Time
Garbage collection pause time (or GC pause) refers to the time the application is paused while the garbage collector performs its work. The length of the pause depends on factors like the amount of memory to be reclaimed and the type of garbage collector used.