What's Actually Happening

Java applications run out of heap memory. OutOfMemoryError is thrown, applications crash, or garbage collection causes performance issues.

The Error You'll See

OutOfMemoryError Java heap space:

bash
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3332)
    at java.util.Arrays.copyOf(Arrays.java:3332)

OutOfMemoryError GC overhead:

bash
java.lang.OutOfMemoryError: GC overhead limit exceeded

Memory warning:

```bash tail -f /var/log/app.log

WARNING: java.lang.OutOfMemoryError: Java heap space ```

Why This Happens

  1. 1.Heap too small - Initial heap size insufficient
  2. 2.Memory leak - Objects not being garbage collected
  3. 3.Large data processing - Processing data larger than heap
  4. 4.Too many objects - Creating too many objects
  5. 5.GC tuning needed - Garbage collection not optimized
  6. 6.Off-heap memory - Not enough native memory
  7. 7.Memory fragmentation - Heap fragmentation

Step 1: Check Current Heap Settings

```bash ps aux | grep java

# Look for -Xmx and -Xms flags

# Check JVM arguments: jcmd <pid> VM.flags

# Get heap usage: jcmd <pid> GC.heap_info

# Check memory: jmap -heap <pid> ```

Step 2: Increase Heap Size

```bash # Set initial and max heap: java -Xms512m -Xmx2g MyApp

# Or in environment: export JAVA_OPTS="-Xms512m -Xmx2g"

# Common settings: # Small: -Xms256m -Xmx512m # Medium: -Xms512m -Xmx2g # Large: -Xms2g -Xmx4g

# As fraction of system memory: # Leave ~25% for OS and other processes ```

Step 3: Check for Memory Leaks

```bash # Generate heap dump: jcmd <pid> GC.heap_dump /tmp/heap.hprof

# Or use jmap: jmap -dump:format=b,file=/tmp/heap.hprof <pid>

# Analyze with tools: # - Eclipse MAT # - VisualVM # - YourKit # - JProfiler

# Check live objects: jcmd <pid> GC.class_histogram | head -20 ```

Step 4: Monitor Memory Usage

```bash # JConsole: jconsole <pid>

# VisualVM: jvisualvm

# Command line: jstat -gc <pid> 1000

# Memory pools: jcmd <pid> VM.info | grep -A 20 "Memory" ```

Step 5: Analyze GC Logs

```bash # Enable GC logging: -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/var/log/gc.log

# Modern Java (11+): -Xlog:gc*:file=/var/log/gc.log

# Check GC logs: tail -f /var/log/gc.log

# Analyze with: # - GCViewer # - GCEasy.io ```

Step 6: Tune Garbage Collection

```bash # Use G1GC (Java 11+ default): -XX:+UseG1GC

# Set max GC pause: -XX:MaxGCPauseMillis=200

# For throughput: -XX:+UseParallelGC

# For low latency: -XX:+UseZGC

# Common settings: -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=45 ```

Step 7: Check Metaspace

```bash # Metaspace is for class metadata # If OutOfMemoryError: Metaspace

# Increase metaspace: -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m

# Check metaspace usage: jcmd <pid> GC.heap_info | grep Metaspace

# Enable class unloading: -XX:+CMSClassUnloadingEnabled ```

Step 8: Handle Large Objects

```bash # For large data: # Process in chunks # Use streaming APIs # Avoid loading all data into memory

# Use off-heap memory: -XX:MaxDirectMemorySize=1g

# For large files: # Use streaming I/O # Use memory-mapped files ```

Step 9: Container Memory Limits

```bash # In Docker/container: # Set JVM heap based on container limit

# Java 10+ automatically detects container limits # For older versions: -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap

# Or set explicitly: java -Xmx$(echo $(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) * 0.75 | bc) MyApp

# In Kubernetes: # Set JVM heap based on container limit env: - name: JAVA_OPTS value: "-Xms512m -Xmx768m" ```

Step 10: Monitor and Alert

```bash # JMX monitoring: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false

# Prometheus JMX exporter: java -javaagent:jmx_prometheus_javaagent.jar=8080:config.yaml -jar app.jar

# Key metrics: # - jvm_memory_used_bytes # - jvm_gc_collection_seconds # - jvm_threads_current ```

Java Heap Space Error Checklist

CheckCommandExpected
Heap sizeps aux grep-Xmx set
Memory usagejcmd GC.heap_infoWithin limits
GC logstail gc.logNo excessive GC
Heap dumpjcmd heap_dumpAnalyze for leaks
Metaspacejcmd GC.heap_infoSufficient
Container limit/sys/fs/cgroupJVM fits

Verify the Fix

```bash jcmd <pid> VM.flags | grep -E "Xmx|Xms"

jcmd <pid> GC.heap_info

jstat -gc <pid> 1000 5

tail -f /var/log/gc.log

jcmd <pid> GC.class_histogram | head -10

ps aux | grep java ```

  • [Fix Java OutOfMemoryError](/articles/fix-java-outofmemoryerror)
  • [Fix Java Application Crash](/articles/fix-java-application-crash)
  • [Fix Docker Out of Memory](/articles/fix-docker-out-of-memory)