Diagnosing and Resolving Metaspace Memory Leak Caused by JAXBContext in Java Backend Services

This article details a step‑by‑step investigation of a Java backend service outage caused by metaspace exhaustion due to repeated JAXBContext creation, including monitoring, dump analysis, code verification, and the final solution of caching JAXBContext and limiting metaspace size.

Qunar Tech Salon
Qunar Tech Salon
Qunar Tech Salon
Diagnosing and Resolving Metaspace Memory Leak Caused by JAXBContext in Java Backend Services

Problem: The online task service generated alerts and some machines went offline; interfaces timed out even though the service process was still running.

Investigation: Using top revealed high CPU usage while memory was fine; GC logs showed frequent Full GC. Analysis indicated that Metaspace was consuming nearly 2.8 GB and not being reclaimed, causing the Full GC loops.

Dump and analysis: A heap dump was captured with jmap -dump:format=b,file=/tmp/15106.bin 15106. MAT struggled to load the dump, so jhat -J-Xmx3000m 15106.bin was used, revealing about 1.8 million class instances, many originating from XML‑to‑object conversion classes.

Root cause: Each XML conversion created a new JAXBContext, which generated class metadata that accumulated in Metaspace, eventually exhausting it.

Verification: The JVM was started with -XX:MaxMetaspaceSize=50m and a test program repeatedly created JAXBContext instances. Monitoring with jconsole showed non‑heap memory growth and OOM when the context was not cached, while using a cached context kept memory stable.

public static void main(String[] args) throws Exception {
    for (int i = 0; i < 10000; i++) {
        Thread.currentThread().sleep(10);
    }
    Field f = ClassLoader.class.getDeclaredField("classes");
    f.setAccessible(true);
    System.out.println("start");
    while (true) {
        JAXBContext context = JaxbUtil.getContext(TuniuPriceRequest.class);
        // JAXBContext context = JAXBContext.newInstance(TuniuPriceRequest.class);
        Vector clzz2 = (Vector) f.get(context.getClass().getClassLoader());
    }
}

Conclusion: The memory leak was definitively caused by repeated creation of JAXBContext. The fix is to cache JAXBContext instances and configure a reasonable Metaspace limit.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Javamemory leakMetaspacegcJAXBContext
Qunar Tech Salon
Written by

Qunar Tech Salon

Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.