Java 内存泄漏 - jmap 不显示 类 但 jstat 显示
Java memory leak - jmap doesn't show the classes but jstat does
我解决了一个奇怪的内存泄漏问题。它特定于 Java8,不会发生在 7u79 上。
我无法访问 Java 代码。
我确切地知道是哪个用户操作导致了泄漏,我知道泄漏是关于 classes(不是堆)的,并且使用 +TraceClassLoading +TraceClassUnloading:[=18 很容易发现有问题的 classes =]
[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... ]
这些 classes 似乎增加了 class 计数器输出 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
问题是,这些 class 永远不会从元空间中被垃圾回收,也不会 [Unloaded]
并且它们不会显示在 jmap -clstats
中。该命令报告的 classes 数量较少,数量没有增加,没有可疑的 class 加载器:
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 选项来阻止这种泄漏吗?
如果有问题 类 无法卸载,那么它必须缓存在应用程序的某个地方,据我了解,您的目标是找到它的位置并为开发人员提供此信息。
您可以尝试使用 Eclipse Memory Analyzer (MAT) 检查您的堆转储,它可以显示问题区域,类 和链接到错误的实例 类.
我推测 JaxB 正在将 类 加载到您的内存中,而这些内存并未被垃圾回收。如果 类 没有被卸载,Metaspace 将不会被清空。
检查 。我认为您可以通过交换依赖项 api 版本或切换额外参数来摆脱此异常:
-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true
我解决了一个奇怪的内存泄漏问题。它特定于 Java8,不会发生在 7u79 上。
我无法访问 Java 代码。 我确切地知道是哪个用户操作导致了泄漏,我知道泄漏是关于 classes(不是堆)的,并且使用 +TraceClassLoading +TraceClassUnloading:[=18 很容易发现有问题的 classes =]
[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... ]
这些 classes 似乎增加了 class 计数器输出 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
问题是,这些 class 永远不会从元空间中被垃圾回收,也不会 [Unloaded]
并且它们不会显示在 jmap -clstats
中。该命令报告的 classes 数量较少,数量没有增加,没有可疑的 class 加载器:
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 选项来阻止这种泄漏吗?
如果有问题 类 无法卸载,那么它必须缓存在应用程序的某个地方,据我了解,您的目标是找到它的位置并为开发人员提供此信息。
您可以尝试使用 Eclipse Memory Analyzer (MAT) 检查您的堆转储,它可以显示问题区域,类 和链接到错误的实例 类.
我推测 JaxB 正在将 类 加载到您的内存中,而这些内存并未被垃圾回收。如果 类 没有被卸载,Metaspace 将不会被清空。
检查
-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true