Understanding Java OOM Errors: Heap, GC Overhead, Metaspace, CodeCache, Direct Memory, and Linux OOM Killer
This article explains the various Java OutOfMemoryError types—including Java heap space, GC overhead limit exceeded, Metaspace, CodeCache, Direct Memory, and Linux OOM Killer—describes their causes, typical symptoms, and provides step‑by‑step troubleshooting and mitigation strategies for developers.
Java heap space
Java heap space OOM is the most common out‑of‑memory error; it occurs when the heap is full, GC cannot keep up, and the allocator cannot allocate new objects, resulting in java.lang.OutOfMemoryError: Java heap space .
Typical resolution steps include dumping the heap, analyzing the dump with tools such as MAT, YourKit, JProfiler or IDEA Profiler, identifying the largest objects, optimizing code to reduce allocations, and increasing JVM heap size or scaling the service.
Common library misuse
Many libraries should be used as singletons to avoid repeated object creation; examples include Apache HttpClient, Gson, and Jackson, where a globally‑maintained instance improves performance and reduces memory pressure.
CloseableHttpClient httpClient = HttpClients.custom()
.setMaxConnPerRoute(maxConnPerRoute)
.setMaxConnTotal(maxConnTotal)
// ...
.build();GC overhead limit exceeded
This error indicates that GC is spending excessive time reclaiming memory while freeing very little, often in low‑traffic scenarios where many reachable objects prevent effective collection, leading to high CPU usage and long GC pauses.
The troubleshooting approach is similar to heap OOM: monitor GC activity, check request volume, pause times, and CPU utilization.
Metaspace/PermGen
Metaspace stores class metadata; it has no default upper bound but can be limited with -XX:MaxMetaspaceSize= . Excessive Metaspace usage can cause Full GC or OOM errors, e.g., java.lang.OutOfMemoryError: Metaspace .
Investigation methods include using Arthas to inspect ClassLoaders, enabling class loading traces with -XX:+TraceClassLoading -XX:+TraceClassUnloading , and recognizing common causes such as excessive reflection, Java agents, and dynamic proxies that generate many classes.
Code Cache
Code Cache holds JIT‑compiled hot code; if it becomes full, the JVM disables the JIT compiler, slowing the application. The default size is around 240 MB/128 MB and can be increased with -XX:ReservedCodeCacheSize= .
Server VM warning: CodeCache is full. Compiler has
been
disabled.Direct Memory
Direct Memory is off‑heap memory used for high‑performance I/O (e.g., Netty). It is allocated via malloc and can cause OOM if it exceeds -XX:MaxDirectMemorySize= , producing java.lang.OutOfMemoryError: Direct buffer memory .
# A fatal error has been detected by the Java Runtime Environment:
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffdbd5d19b4, pid=1208, tid=0x0000000000002ee0
# JRE version: Java(TM) SE Runtime Environment (8.0_301-b09)
# ...Linux OOM Killer
When the operating system runs out of memory, the Linux OOM Killer may terminate the JVM process, especially in container environments. This usually points to native memory leaks, often caused by third‑party libraries or JDK components such as Inflater/Deflater.
Native memory investigation involves tools like pmap , strace , and alternative allocators (jemalloc, tcmalloc) to trace allocations.
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.