我们在 Wildfly 上部署了一个企业应用程序。用于运行的Java版本是11.0.22+7-LTS。 我们在执行环境中看到一个奇怪的问题。每次我们收集实时堆转储时,我们都会看到“java.lang.ClassValue$ClassValueMap”对象保留了大量内存,即使它无法访问。
当我们将堆转储导入 MAT 时,它清楚地显示“无法访问”。 无法到达和泄漏嫌疑人
然而 GIGC 并没有清理空间
为了收集堆转储,我们使用命令
JAVA_HOME/bin/jmap -dump:live,file=/opt/smp/heap.hprof <pid>
我们使用的 JVM 参数是
-Xms8192m -Xmx8192m -XX:+UseG1GC -XX:+PrintGC -XX:G1HeapRegionSize=33554432 -XX:+HeapDumpOnOutOfMemoryError -Djava.net.preferIPv4Stack=true -XX:+AlwaysPreTouch -Xlog:gc*:file=/log/gc.log:time:filecount=5,filesize=3m -XX:HeapDumpPath=/log/heapDump.hprof -Dfile.encoding=UTF-8 -Dhazelcast.health.monitoring.level=OFF -Djava.net.preferIPv4Stack=true -Djboss.as.management.blocking.timeout=999999 -Djboss.home.dir=/opt/smp20/belsmp02_8404 -Djboss.node.name=belsmp02_7404 -Djgroups.bind_addr=10.xxx.xx.xxx -Djgroups.tcp.address=10.xxx.xx.xxx -Dsmp.database.type=oracle -Djboss.server.log.dir=/log -Djboss.server.temp.dir=/tmp -Djboss.server.data.dir=/data -Dlogging.configuration=file:/data/logging.properties
在生产中,OOM堆转储也存在同样的问题。 java.lang.ClassValue$ClassValueMap 被保留并且不会被 GC 清理。
有什么指示什么时候会发生这种情况吗?接下来我们可以尝试什么?
我们尝试增加 G1HeapRegionSize。这没有帮助。我们还没有配置 GC 完成的时间限制。
原来是jdk的dynalink模块的bug。这个问题 - https://github.com/szegedi/dynalink/issues/15 是我问题的根本原因。