CodeToConcept
About

java

java Tutorials

Introduction
Java Variables
Java Data Types
Java Type Casting
Java Operators
Java Input/Output
Java Class & Object
java Method
Java Constructor
Java this keyword
Java super keyword
Java Method Overloading and Overriding
Java Interface
Java Abstract Class
Java Memory Management
Design Patterns
JDBC (Database Connectivity)
Java IDEs

java Tutorials

Introduction
Java Variables
Java Data Types
Java Type Casting
Java Operators
Java Input/Output
Java Class & Object
java Method
Java Constructor
Java this keyword
Java super keyword
Java Method Overloading and Overriding
Java Interface
Java Abstract Class
Java Memory Management
Design Patterns
JDBC (Database Connectivity)
Java IDEs

Sample Question

Think it through, then check the tutorial.

CodeToConcept

Quickly learn through simple, structured, and practical coding tutorials. Build your confidence from step zero to real-world experience.

© 2026 CodeToConcept. All rights reserved.

Quick Links

AboutTutorials

Tutorials

JavaHTMLCSS

Support

Privacy PolicyTerms of ServiceContact
GitHubTwitterYouTube

Java Memory Management

Java manages memory for objects and for the work each thread performs. We create and use objects, while the JVM tracks their storage and decides when unused objects can be collected. This reduces manual memory work, but we still need to avoid keeping objects longer than necessary.

Values, Objects, and References

A primitive variable holds a value such as 12 or true. A reference variable can refer to an object or contain null. Two references can point to the same object. Changing one reference does not change the other reference.

class Person {
    String name;
}
 
public class HelloWorld {
    public static void main(String[] args) {
        Person first = new Person();
        first.name = "Mira";
        Person second = first;
        first = null;
        System.out.println(second.name);
    }
}

Output:

Mira

The Person object is still reachable through second. Assigning null to first does not destroy the object.

Heap Memory

The heap is the JVM runtime area from which objects and arrays are allocated. Instance fields are part of their objects. The heap is shared by threads, so access to shared mutable objects may need synchronization.

Thread Stacks

Each JVM thread has its own stack of method-call frames. A frame contains local variables and information needed to continue the call. When a method returns, its frame is removed. An object referenced by a local variable may still be reachable elsewhere after that call returns.

Do not use the rule "primitives always live on the stack and references always live on the heap." A primitive can be an object field, and a reference can be a local variable. The JVM may also optimize allocations while keeping the required program behavior.

Method Metadata and Metaspace

The JVM specification defines a method area for class-level information. In HotSpot, much class metadata is stored in native memory called Metaspace. Metaspace is not a second heap for normal application objects. Exact memory layout is an implementation detail rather than a rule every JVM must copy.

Garbage Collection

Garbage collection reclaims memory from objects that are no longer reachable in the way the collector considers live. Active threads, static fields, and other JVM roots can keep objects reachable. A cycle of objects is not enough to prevent collection if the whole cycle is unreachable.

Calling System.gc() is a request, not a promise that collection happens immediately. There is no reliable program output that proves the exact moment an ordinary object will be collected.

Example: Stop Keeping Old Results

import java.util.ArrayList;
import java.util.List;
 
public class HelloWorld {
    public static void main(String[] args) {
        List<String> recentNames = new ArrayList<>();
        recentNames.add("Mira");
        recentNames.add("Ravi");
        System.out.println(recentNames.size());
        recentNames.clear();
        System.out.println(recentNames.size());
    }
}

Output:

2
0

clear() removes the list's references to its elements. The list itself remains usable, and its backing storage may remain allocated. These string literals may also remain reachable through other references; this example does not claim they are collected.

Memory Leaks in Java

A Java application can run out of memory even with a garbage collector. For example, a static list that keeps every request result forever retains those results. Other common causes include caches without limits and listeners that are registered but never removed.

Memory and External Resources

A file handle or database connection is not just ordinary heap storage. Close resources when finished rather than waiting for garbage collection. Use try-with-resources for AutoCloseable resources. Do not depend on finalizers; finalization is deprecated for removal and does not provide timely cleanup.

OutOfMemoryError and StackOverflowError

OutOfMemoryError means the JVM cannot satisfy a memory request in some required area. Increasing heap size may help a capacity problem but does not repair unlimited retention. StackOverflowError often follows too many nested calls, such as recursion that never reaches its stopping condition.

First Steps When Investigating Memory Use

Check how memory changes over time, not just one reading. Look for growing collections and caches. Compare heap data or recordings to find which paths retain objects. Consider tools such as Java Flight Recorder, JDK Mission Control, and heap analysis tools. Avoid guessing from the number of objects created alone.

Easy Way to Remember

  • A reference can keep an object reachable.
  • A method returning does not necessarily make all its objects unreachable.
  • The garbage collector chooses when to reclaim unused object memory.
  • Close files and connections explicitly, and keep caches and collections bounded.

See you in next page....🙂

← Autoboxing & UnboxingDesign Patterns →
← Autoboxing & UnboxingDesign Patterns →