Why My Spring Boot App Swallowed 7 GB RAM: Uncovering Native Memory Leaks
After migrating a project to the MDP framework based on Spring Boot, the author observed excessive swap usage and physical memory consumption of 7 GB despite a 4 GB heap limit, and through a series of JVM, system, and native‑code diagnostics identified Spring Boot’s ZipInflaterInputStream native‑memory leak caused by unchecked package scanning.
Background
To better manage a project, the team migrated a module to the MDP framework (based on Spring Boot). Soon the system repeatedly reported high swap usage. Although the JVM was configured with a 4 GB heap, the process consumed up to 7 GB of physical memory, which was abnormal.
JVM options used:
-XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:+AlwaysPreTouch -XX:ReservedCodeCacheSize=128m -XX:InitialCodeCacheSize=128m -Xss512k -Xmx4g -Xms4g -XX:+UseG1GC -XX:G1HeapRegionSize=4MTop command showed the memory usage.
Investigation Process
1. Locate memory at the Java level
Added -XX:NativeMemoryTracking=detail and restarted the service. jcmd <pid> VM.native_memory detail displayed the distribution of native memory, showing that the committed memory reported by the command was smaller than the physical usage because it does not include native allocations made by C code.
Using pmap revealed many 64 MB address ranges that were not listed by jcmd, suggesting native allocations.
2. Locate native memory at the system level
Since Java‑level tools could not pinpoint the culprit, system tools were used.
gperftools
gperftools profiling showed a peak of about 3 GB allocated via malloc, then dropping to 700‑800 MB.
The pattern suggested that memory was allocated with mmap/brk rather than malloc.
strace
Running strace -f -e brk,mmap,munmap -p <pid> captured the memory‑request system calls but did not reveal suspicious allocations during normal operation.
Repeating the trace while the application started showed many 64 MB mmap regions, matching the earlier pmap output.
jstack
Using the thread IDs from strace, jstack <pid> identified the threads that performed the large mmap calls.
The culprit turned out to be the Meituan Configuration Center (MCC) which uses Reflections to scan all JAR packages. The scanning process invokes Spring Boot’s ZipInflaterInputStream, which uses Inflater (native code) to decompress JARs and allocates off‑heap memory that is only released by the finalizer.
After configuring MCC to scan only specific packages, the memory problem disappeared.
3. Why the off‑heap memory was not released
Spring Boot wraps InflaterInputStream but does not explicitly free the native memory; it relies on the Inflater finalizer. In the observed version, the finalizer was not triggered promptly, and the underlying glibc memory allocator kept the freed pages in per‑thread arenas (64 MB each), so the OS memory usage remained high.
Updating to Spring Boot 2.0.5, which adds an explicit close() to ZipInflaterInputStream, resolves the issue.
Conclusion
The excessive native memory consumption was caused by MCC’s unrestricted package scanning, which caused Spring Boot’s ZipInflaterInputStream to allocate large off‑heap buffers that were only released by GC finalization. Upgrading Spring Boot or limiting the scan path eliminates the leak, and understanding the interaction between the JVM, native allocators, and glibc arenas is essential for diagnosing similar memory‑usage anomalies.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack 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.
