【发布时间】:2017-01-29 16:16:45
【问题描述】:
我解决了一个奇怪的内存泄漏问题。它特定于 Java8,不会发生在 7u79 上。
我无权访问 Java 代码。 我确切地知道哪个用户操作导致了泄漏,我知道泄漏是关于类(而不是堆),并且通过 +TraceClassLoading +TraceClassUnloading 很容易发现有问题的类:
[Loaded com.mastercard.mcwallet.sdk.xml.allservices.ShoppingCartRequest$JaxbAccessorF_oAuthToken from __JVM_DefineClass__]
[Loaded com.mastercard.mcwallet.sdk.... thousand similar classes per one user action... ]
这些类似乎将类计数器输出增加了jstat -class:
Loaded Bytes Unloaded Bytes Time
14045 26138.8 0 0.0 110.00 << buggy user action
14675 26754.6 0 0.0 110.05
15300 27364.9 0 0.0 110.10
15304 27370.9 0 0.0 110.11
15304 27370.9 0 0.0 110.11
15304 27370.9 0 0.0 110.11
15306 27374.0 0 0.0 110.11
15306 27374.0 0 0.0 110.11
15306 27374.0 0 0.0 110.11
15306 27374.0 0 0.0 110.11 << buggy user action
15930 27982.2 0 0.0 110.18
16553 28589.3 0 0.0 110.23
16553 28589.3 0 0.0 110.23
问题是这些类永远不会从元空间中进行垃圾收集,永远不会从 [Unloaded] 中收集,并且它们不会显示在 jmap -clstats 中。该命令报告的类数量较少,数量没有增加,没有可疑的类加载器:
class_loader classes bytes parent_loader alive? type
<bootstrap> 2574 4493256 null live <internal>
0x0000000087d016d0 1 1471 0x000000008237f088 dead sun/reflect/DelegatingClassLoader@0x00007ff4135d02d0
... some lines omitted ...
0x000000008237f088 6505 12228227 0x0000000080383938 dead org/apache/catalina/loader/WebappClassLoader@0x00007ff411546ad0
... some lines omitted ...
total = 600 14002 25351427 N/A alive=1, dead=599 N/A
这是否敲响了警钟或带来了我可以传递给程序员的任何提示?他们说他们无法找到泄漏点。我可以通过摆弄 JVM 选项来阻止这种泄漏吗?
【问题讨论】:
-
只有
MetaSpace的问题?heap呢?还能提供Java进程内存使用统计吗? -
只有元空间,堆是稳定的,不是满的。究竟是什么统计数据?
-
我的意思是 Java 进程内存使用增长的速度有多快?
-
每个“错误用户操作”从操作系统分配大约 2 MB(
pmap工具甚至显示一个单独的 2 MB 段)。 -
你是否尝试过使用不同的 GC 算法,例如 G1
-XX:+UseG1GC?或者您可以尝试将-XX:MaxMetaspaceSize=<NNN>设置为预期定义Metaspace的大小。
标签: java memory-leaks java-8 jmap