排查Java的内存问题(5)

“jmap –permstat”会展现类加载器的统计数据,比如类加载器、类加载器所加载的类的数量以及这些类加载已死亡还是尚在存活。它还会告诉我们PermGen中interned字符串的总数,以及所加载的类及其元数据所占用的字节数。如果我们要确定是什么内容占满了PermGen,那么这些信息是非常有用的。如下是一个示例的输出,展现了所有的统计信息。在列表的最后一行我们能够看到有一个总数的概述。

$ jmap -permstat 29620
Attaching to process ID 29620, please wait...
Debugger attached successfully. Client compiler detected.
JVM version is 24.85-b06
12674 intern Strings occupying 1082616 bytes. finding class loader instances ..
 done. computing per loader stat ..done. please wait.. computing liveness.........................................done.
class_loader classes bytes parent_loader  alive?  type
<bootstrap> 1846 5321080  null  live  <internal>
0xd0bf3828  0  0   null  live    sun/misc/Launcher$ExtClassLoader@0xd8c98c78
0xd0d2f370  1  904   null  dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0c99280  1  1440   null  dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0b71d90  0  0  0xd0b5b9c0 live   java/util/ResourceBundle$RBClassLoader@0xd8d042e8
0xd0d2f4c0  1  904   null  dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0b5bf98  1  920  0xd0b5bf38 dead  sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0c99248  1  904   null  dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f488  1  904   null  dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0b5bf38  6  11832  0xd0b5b9c0 dead  sun/reflect/misc/MethodUtil@0xd8e8e560
0xd0d2f338  1  904   null  dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f418  1  904   null  dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f3a8  1  904  null  dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0b5b9c0  317 1397448 0xd0bf3828 live sun/misc/Launcher$AppClassLoader@0xd8cb83d8
0xd0d2f300  1  904   null  dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f3e0  1  904   null  dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0ec3968  1  1440   null  dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0e0a248  1  904   null  dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0c99210  1  904   null  dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f450  1  904   null  dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f4f8  1  904   null  dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0e0a280  1  904   null  dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
 
total = 22   2186    6746816  N/A  alive=4, dead=18   N/A

从Java 8开始,jmap –clstats <pid>命令能够打印类加载器及其存活性的类似信息,不过它所展现的是Metaspace中已加载的类的数量和大小,而不再是PermGen。

jmap -clstats 26240
Attaching to process ID 26240, please wait...
Debugger attached successfully. Server compiler detected. JVM version is 25.66-b00 finding class loader instances ..done. computing per loader stat ..done. please wait.. computing liveness.liveness analysis may be inaccurate ...
class_loader  classes bytes parent_loader alive? type
<bootstrap>        513 950353 null live <internal>
0x0000000084e066d0 8 24416  0x0000000084e06740 live sun/misc/Launcher$AppClassLoader@0x0000000016bef6a0
0x0000000084e06740 0 0      null live sun/misc/Launcher$ExtClassLoader@0x0000000016befa48
0x0000000084ea18f0 0 0 0x0000000084e066d0 dead java/util/ResourceBundle$RBClassLoader@0x0000000016c33930
 
total = 4   521  974769      N/A     alive=3, dead=1  N/A

堆转储

正如我们在前面的章节所提到的,Eclipse MAT、jhat、Java VisualVM、JOverflow JMC插件和Yourkit这些工具都能分析堆转储文件,从而分析排查OutOfMemoryError。在解决PermGen和Metaspace的内存问题时,堆转储同样是有用的。Eclipse MAT提供了一个非常好的特性叫做“Duplicate Classes”,它能够列出被不同的类加载实例多次加载的类。由不同的类加载器加载数量有限的重复类可能是应用设计的一部分,但是,如果它们的数量随着时间推移不断增长的话,那么这就是一个危险的信号,需要进行调查。应用服务器托管多个应用时,它们运行在同一个JVM中,如果多次卸载和重新部署应用的话,经常会遇到这种状况。如果被卸载的应用没有释放所有它创建的类加载器的引用,JVM就不能卸载这些类加载器所加载的类,而新部署的应用会使用新的类加载器实例重新加载这些类。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/8897945a0be00fadb00880f35eefe05e.html