Java memory management is handled automatically by the JVM, which allocates, manages, and reclaims memory through automatic garbage collection. This prevents memory leaks and makes Java safer than languages that use manual memory allocation.
Java memory is divided into two main areas:
- Heap Memory
- Stack Memory
Plus additional areas like Method Area, PC Registers, and Native Method Stack.
Java divides memory into major runtime areas:
- Stores objects, arrays, instance variables
- Shared among all threads
- Garbage Collector works only in Heap
- Largest memory area in JVM
-
Young Generation
- Eden space
- Survivor space S1/S2
-
Old Generation (Tenured)
Newly created objects are allocated here.
- Eden → new objects created
- Survivor 1
- Survivor 2
Objects surviving multiple GC cycles are promoted to the Old Generation.
- Contains long-living objects
- Full GC takes place here
- Heavy operations, more time-consuming
Each thread has its own Stack. Every method call creates a stack frame that stores:
- Local variables (primitives)
- References to objects in heap
- Return values
- Method call information
Stack is LIFO (Last In First Out).
When a method finishes, its stack frame is removed.
Each thread has its own stack, so stack memory is not shared.
Stores:
- Class bytecode
- Static variables
- Method definitions
- Constant pool
- Field metadata
- Constructor information
Shared across all threads.
Each thread has a small memory area called a PC register used to track the current executing instruction. Because of this we are able to have multiple threads executing independently.
For executing native (non-Java) code, like:
System.loadLibrary("xyz");Java uses garbage collection to remove unused objects from heap.
If there are no live references pointing to it.
Example:
Student s = new Student();
s = null; // eligible for GCOr:
Student s1 = new Student();
Student s2 = new Student();
s1 = s2; // Old object previously in s1 is now eligible- Single-threaded
- Suitable for small applications
- Multiple threads
- Best for CPU-intensive apps
- Low pause GC
- Region-based
- Low pause
- Balanced performance
Even with GC, logical memory leaks can occur:
- Unclosed resources
- Static references holding objects
- List or Map growing indefinitely
- Listeners not removed
- Cache without eviction policy
Example:
static List<Object> list = new ArrayList<>();
void add() {
list.add(new Object()); // stays forever (static)
}Earlier, Java used finalize() to clean up resources.
Now it's deprecated due to unpredictability.
Modern cleanup uses:
- try-with-resources
- AutoCloseable
Example:
try (FileInputStream fs = new FileInputStream("a.txt")) {
// auto-close
}- Method is invoked
- Stack frame created
- Variables allocated
- Objects created in heap
- Methods return → stack frame destroyed
- Objects without references → GC
| Feature | Stack | Heap |
|---|---|---|
| Stores | Local variables, references, method frames | Objects, arrays |
| Access Speed | Fast | Slow |
| Managed By | JVM | Garbage Collector |
| Thread-Safety | Each thread has its own | Shared across threads |
| Memory Size | Small | Large |
| Lifetime | Ends after method | Until GC clears |
public void test() {
int x = 10; // stack
String s = "hello"; // SCP reference
Student st = new Student(); // heap
}Memory distribution:
| Code | Memory |
|---|---|
x = 10 |
Stack |
"hello" |
String Constant Pool |
st reference |
Stack |
| Student object | Heap |
The JVM may move an object from heap → stack if:
- Object does not escape the method
- No references exist outside method
This reduces GC load.
Stack stores method frames & primitives; heap stores objects.
Automatic removal of unused objects.
Thrown when heap or method area memory is exhausted.
Objects remain referenced unintentionally, preventing GC.
Young = new objects; Old = long-lived objects.
-
Java memory is divided into Heap, Stack, Method Area, and more.
-
Heap → objects; Stack → method calls, primitives.
-
Garbage Collector automatically removes unused objects.
-
Memory leaks can still occur due to improper code.
-
Modern GC uses G1 and region-based memory management.
-
String Constant Pool resides in heap (Java 7+).
