Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to analyze memory leaks in Java 8 compressed class space?

Some Context: We have upgraded the environment of a web application from running on Java 7 to running on Java 8 and Tomcat 8 (64-bit arch, Heap size about 2 GB, PermGen size=256 MB, no constraints on metaspace size). After a while, we started getting the following error:

java.lang.OutOfMemoryError: Compressed class space

which means that the space needed for UseCompressedClassPointers exceeded CompressedClassSpaceSize. At that moment VisualVM showed a 2 GB metaspace size.

Now with the VisualVM tool, we can see the Metaspace size is constatnly increasing with every request about 3 MB, however the heap does not seem to do so. The heap usage has a saw zigzag shape going back to the same low point after every GC.

I can tell that the application is leaking Metadata only when using a Java JAXB operation, but I couldn't prove it with VisualVM.

The application depends on webservices-rt-1.4 as a JAXB implementation provider. The application uses marshalling, unmarshalling. The class generation from XSD is done with maven-jaxb2-plugin-0.13.1.


Update:

After tracing class loading and unloading, I found out that the same JAXB classes is loaded into memory by WebAppClassLoader multiple times but never cleaned up. Moreover, there are no instances to them in the heap. I debugged and I saw that JDK is calls the method javax.xml.bind.JAXBContext com.sun.xml.bind.v2.ContextFactory.createContext by reflection and that's when the class are created.

I though the classes are cleaned up by GC. Is it the responsibility of the classLoader to clean up?


Questions: Is there a way to analyze the metaspace objects? Why do I have a leak in metaspace but not in heap? aren't they related? Is that even possible?

Why would the app work fine with PermGen but not Metaspace?

like image 849
Bassam Avatar asked Feb 05 '23 19:02

Bassam


1 Answers

I am facing similar issue.

In my case, memory leak was caused by JAXBContext.newInstance(...) invoke.

Solutions:

  • wrap this new instance as singleton (https://github.com/javaee/jaxb-v2/issues/581) or
  • use -Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true VM parameter, like in answer Old JaxB and JDK8 Metaspace OutOfMemory Issue
like image 124
maki888 Avatar answered Feb 08 '23 10:02

maki888