JVM Memory Structure: Understanding the Heap

1. Structure Diagram

Heap memory structure overview

2. Heap

Heap illustration

  1. Objects reside in the heap: their size is unpredictable and can change dynamically.
  2. The stack holds primitive values and object referances; each reference is typically 4 bytes.

2.1 Characteristics

  1. Nearly all objects are allocated on the heap.
  2. Heap memory is fully managed by the JVM through automatic garbage collection.
  3. It can throw OutOfMemoryError when space is exhausted.

2.2 Linking Stack to Heap

Stack-to-heap reference process

2.3 Example

Heap example

The MessageHolder instances are allocated on the heap. Class metadata for MessageHolder is stored in the method area. Local variables ref1 and ref2 inside main reside on the Java stack and point to the two instances on the heap.

3. Memory Overflow

Memory overflow occurs when the JVM cannot allocate space for a new object, even after triggering garbage collection.

3.1 Heap Overflow Code Example

public class MemoryBlocker {
    // Pre-allocate a block to make heap exhaustion faster
    byte[] payload = new byte[128 * 1024];

    public static void main(String[] args) {
        List<MemoryBlocker> container = new ArrayList<>();
        // Keep allocating until heap is full
        while (true) {
            container.add(new MemoryBlocker());
        }
    }
}

Result:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.example.MemoryBlocker.<init>(MemoryBlocker.java:8)
at com.example.MemoryBlocker.main(MemoryBlocker.java:14)

3.2 Common Overflow Scenarios

  1. Loading excessively large data sets, for example fetching an entire database table at once.
  2. Collection objects that hold references after use, preventting garbage collection.
  3. Infinite loops or loops that create too many objects.

3.3 Prevention Strategies

  • Increase heap size via JVM startup parameters.
  • Examine error logs for clues preceding the OutOfMemoryError.
  • Conduct code reviews and static analysis.

3.3.1 Code Review Checklist

  1. Identify infinite loops or unbounded recursive calls.
  2. Avoid large loops that instantiate new objects repeatedly.
  3. Ensure database queries use pagination instead of retrieving all rows.
  4. Clear List, Map, and similar collections after use—strong references prevent GC.
  5. Nullify temporary references as soon as they leave scope to hint the garbage collector.
  6. Minimize heavy String usage.
  7. Use static fields sparingly; they are never garbage-collected while the class is loaded.
  8. Avoid creating large objects inside collections that may trigger sudden full GC.
  9. Leverage object-pooling patterns where appropriate.
  10. Refrain from creating objects inside frequently invoked methods.

3.3.2 Reducing String Allocations

Avoid repeated String concatenation that produces many intermediate objects. Prefer StringBuilder (or StringBuffer in thread-safe contexts).

String a = "hello";
String b = "world";
// Each concatenation may create new objects; prefer StringBuilder for repeated operations.
StringBuilder builder = new StringBuilder();
builder.append(a).append(b);
String result = builder.toString();

3.3.3 Object Pooling

Long-lived objects that reference short-lived objects can cause memory leaks. For example, a large collection holding large data objects should be processed in chunks, releasing each chunk immediately after processing.

3.3.4 Avoid Frequent Object Creation

Instead of new inside hot methods, consider reusing objects via containers such as Hashtable or Vector-based pools, retrieving instances rather than allocating and discarding them repeatedly.

Tags: JVM heap Memory Overflow OutOfMemoryError garbage collection

Posted on Sat, 20 Jun 2026 18:02:37 +0000 by atomm