Bas*_*sam 2 memory-leaks metadata jaxb out-of-memory java-8
一些上下文:我们已将Web应用程序的环境从在Java 7上运行升级到在Java 8和Tomcat 8上运行(64位arch,堆大小约2 GB,PermGen大小= 256 MB,对元空间大小没有约束).过了一会儿,我们开始收到以下错误:
java.lang.OutOfMemoryError:压缩的类空间
这意味着UseCompressedClassPointers所需的空间超出了CompressedClassSpaceSize.那时VisualVM显示了2 GB的元空间大小.
现在使用VisualVM工具,我们可以看到Metaspace大小随着每个请求大约3 MB而不断增加,但是堆似乎没有这样做.堆使用具有锯齿形状,在每个GC之后返回到相同的低点.
我可以告诉应用程序仅在使用Java JAXB操作时泄漏元数据,但我无法用VisualVM证明它.
该应用程序依赖于webservices-rt-1.4作为JAXB实现提供程序.该应用程序使用编组,解组.XSD的类生成是使用maven-jaxb2-plugin-0.13.1完成的.
更新:
在跟踪类加载和卸载之后,我发现WebAppClassLoader多次将相同的JAXB类加载到内存中,但从未清理过.而且,堆中没有实例.我调试了,我看到JDK通过反射调用方法javax.xml.bind.JAXBContext com.sun.xml.bind.v2.ContextFactory.createContext,这是在创建类时.
我虽然这些课程都是由GC清理的.是否负责清理classLoader?
问题:有没有办法分析元空间对象?为什么我在元空间中有泄漏而在堆中没有泄漏?他们不相关吗?这甚至可能吗?
为什么应用程序可以正常使用PermGen而不是Metaspace?
小智 5
我面临类似的问题.
在我的情况下,内存泄漏是由JAXBContext.newInstance(...)
调用引起的.
解决方案:
-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true
VM参数,就像回答Old JaxB和JDK8 Metaspace OutOfMemory Issue一样