我正在尝试解决 permgen 泄漏问题,并想就如何解释 jmap -permstat 的输出向你们征求意见。
假设我有一个 jmap -permstat 报告,如下所示:
class_loader classes bytes parent_loader alive? type
<bootstrap> 4791 25941568 null live <internal>
0x00000007203ed508 0 0 0x00000007203ed228 dead com/example/object/SomeObjectType$FirstClassLoader@0x0000000something1
0x000000071dc17620 1 3056 0x0000000705e692a8 dead sun/reflect/DelegatingClassLoader@0x0000000something4
0x000000071f26a898 0 100 null dead com/example/object/SomeClassLoader@0x0000000something3
0x0000000721c6dba0 0 100 null dead com/example/object/SomeClassLoader@0x0000000something3
0x000000071e36df20 0 100 null dead com/example/object/SomeClassLoader@0x0000000something3
0x000000072157c1b8 339 2069112 0x000000072157b8d8 dead com/example/object/SomeObjectType$SecondClassLoader@0x0000000something2
0x00000007128b7830 1 1912 0x0000000700056db8 dead sun/reflect/DelegatingClassLoader@0x0000000something4
0x0000000707634360 1 3088 0x0000000700056db8 dead sun/reflect/DelegatingClassLoader@0x0000000something4
以下是我对上述输出的解释——请纠正我在此过程中所犯的任何错误。
“类型”列中的值不是唯一的。我们看到一些对象出现了 3 次。但是,class_loader 的值在所有三个中都是唯一的;因此,它们中的每一个都是一个独特的对象,占据着永久空间。在本例中,每个占用 100 个字节;因此,300 字节的 permgen 空间被 SomeClassLoader 类型的对象占用。
如果 classes 值非零,则此对象必须是某种类加载器,这指的是它引用的类的数量。(注意:在实际文件中,这三个对象在字节列中都有零;我为这个例子添加了值。在实际实践中,我猜测如果类列中有 0,则没有办法bytes 值可以是除零以外的任何值。)
如果存活值为“dead”,则意味着对象已准备好进行垃圾回收,但 JVM 并未这样做。关于为什么会出现这种情况的原因需要单独讨论。
如果 parent_loader 列中有值,那么这是一个被另一个类加载器引用的对象,并且在该对象被垃圾回收之前不能被垃圾回收。
最后:1)如果我在报告中看到 500 行都列出了相同的类型,2)但它们列出了不同的 class_loader 值,3)那么我可以将字节列 4)中的值相加,这将准确地表示多少permgen 空间被该类型的对象占用。
它是否正确?谢谢!