Skip to content
java.lang.OutOfMemoryError: Java heap space

java.lang.OutOfMemoryError: Java heap space

DodaTech 3 min read

OutOfMemoryError: Java heap space means the JVM exhausted all heap memory and the GC cannot free enough. The application cannot recover and must be restarted.

What It Means

The Java heap is the region of memory where all object instances and arrays are allocated. When the heap is full and the GC cannot free enough space for a new allocation, the JVM throws OutOfMemoryError. The JVM cannot recover from this — the application must be restarted.

Why It Happens

  • The heap size is too small for the application’s workload.
  • A memory leak prevents objects from being garbage collected.
  • You’re loading huge files or datasets entirely into memory.
  • An infinite loop keeps allocating new objects.
  • String intern pool, class metadata, or off-heap memory fills up.
  • A caching layer grows without bound.

How to Fix It

1. Increase the heap size

# Set maximum heap to 2 GB
java -Xmx2g -jar myapp.jar

# Set initial heap to 512 MB and max to 4 GB
java -Xms512m -Xmx4g -jar myapp.jar

2. Generate a heap dump for analysis

# Auto-dump on OOM
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./dump.hprof -Xmx2g -jar myapp.jar

Open the .hprof file with Eclipse MAT or VisualVM to find which objects use the most memory.

3. Fix memory leaks — close resources

// BUG: InputStream never closed
public void readFile(String path) throws IOException {
    InputStream in = new FileInputStream(path);
    // ... read data, but never call in.close()
}

// FIX: try-with-resources (auto-closes)
public void readFile(String path) throws IOException {
    try (InputStream in = new FileInputStream(path)) {
        // ... read data
    }  // in.close() called automatically here
}

4. Clear collections when no longer needed

// BUG: cache grows forever
static List<byte[]> cache = new ArrayList<>();

public void process(byte[] data) {
    cache.add(data);  // never removed
}

// FIX: use a bounded cache
static Map<String, byte[]> cache = new LinkedHashMap<>() {
    @Override
    protected boolean removeEldestEntry(Map.Entry<String, byte[]> eldest) {
        return size() > 100;  // max 100 entries
    }
};

5. Use streaming for large files

// BUG: loads entire file into memory
byte[] allBytes = Files.readAllBytes(Paths.get("huge-file.dat"));

// FIX: process as a stream
try (Stream<String> lines = Files.lines(Paths.get("huge-file.dat"))) {
    lines.forEach(line -> processLine(line));
}
What's the default heap size?
On most JVMs, the default max heap is 25% of available physical RAM (with a minimum of 128 MB). On containers, it’s 25% of the container’s memory limit. Use java -XX:+PrintFlagsFinal | grep MaxHeapSize to see your exact default.
Does increasing -Xmx always fix the problem?
Temporarily yes, but it only delays the crash. If you have a memory leak, the heap will fill up again regardless of how large you make it. Always investigate the root cause with a profiler or heap dump before simply raising the limit.
Can I catch OutOfMemoryError in my code?
You can catch it, but it’s unreliable. The JVM may be in an unstable state after throwing it. Some operations may fail even in the catch block. The best practice is to detect the condition early (e.g., monitor Runtime.getRuntime().maxMemory()) and degrade gracefully.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro