微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

元空间增长,无效的类加载器和GC

如何解决元空间增长,无效的类加载器和GC

我们遇到了一种情况,其中springboot微服务的元空间保持增长,但是堆运行良好。

jmap -clstats显示存在以下类型的无效类装入器。

0x00000000e3c8e3c8 1 4087 0x00000000e0004d18 死com / sun / org / apache / xalan / internal / xsltc / trax / TemplatesImpl $ TransletClassLoader @ 0x000000010087c7e8

在最初的高水位标记GC被触发时,我看到了元空间的下降。在由于定义的Metaspacesize触发此强制GC之后,我看到Metaspace不断增长,并且我看到在Metaspace中保留了更多的同类型的失效classloader。我确实看到了一些GC活动,但是Metaspace消耗没有下降。但是,如果我通过visualvm强制进行GC收集,则将卸载大量类,并且元空间消耗将恢复到启动服务时的状态。

为什么JVM管理的GC不会卸载这些死掉的类加载器,而强制卸载呢?如果是弱/软/幻像引用的原因,那么这是否也不适用于强制GC?

这是在Java8上。谁能提供一些有关我下一步应该做什么的指示?显然存在泄漏,因此有没有办法知道TemplatesImpl $ TransletClassLoader的父类加载器?

感谢任何帮助。

解决方法

第一件事是,JVM仅在Full GC期间清除Metaspace,而在Young GC期间不清除。因此,您所看到的行为是预期的。

在最初的高水位标记GC触发时,我发现元空间下降。

如果检查GC跟踪,将看到System.GC()调用。那是完整的GC。

但是,如果我通过visualvm强制进行GC收集,则将卸载大量类,并且元空间消耗将恢复到启动服务时的状态。

同样,这将是由visualvm触发的完整GC,并且可以在GC跟踪中看到。这就是为什么看到利用率下降的原因。

根据您提供的描述,我认为您没有类加载器泄漏,因为在Full GC期间所有内容都已清除。根据我的经验,如果应用程序不必要地使某些对象保持活动状态,因此即使在Full GC中也没有收集到垃圾,我只会将其视为“内存泄漏”。对于您的情况,我建议使用-XX:MaxMetaspaceSize标志来限制元空间的大小。当占用率达到该阈值时,JVM将自动触发Full GC,并且正如您所注意到的,Metaspace使用率将下降。明智地设置该限制,因为值太低会导致java.lang.OutOfMemoryError: Metaspace问题。

有关here,可以找到有关Metaspace的更多详细信息。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?