Java内存泄漏 – jmap不显示类,但jstat不会显示

我排除了一个奇怪的内存泄漏.它特定于 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

事情是这些类从来没有从Metaspace垃圾回收,从来没有[卸载],并且它们不会显示在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选项来阻止这种泄漏吗?

解决方法

我推测JaxB正在将类加载到你的内存中,而不是垃圾回收.如果类没有卸载,Metaspace将不会被清空.

检查JaxB memory issue for Java 8.我想你可以通过交换依赖api版本或通过切换一个额外的参数来摆脱这个异常:

-Dcom.sun.xml.bind.v2.bytecode.Classtailor.noOptimize=true

相关文章

应用场景 C端用户提交工单、工单创建完成之后、会发布一条工...
线程类,设置有一个公共资源 package cn.org.chris.concurre...
Java中的数字(带有0前缀和字符串)
在Java 9中使用JLink的目的是什么?
Java Stream API Filter(过滤器)
在Java中找到正数和负数数组元素的数量