如何解释“jmap -permstat”的输出?

时间:2012-11-13 17:49:55

标签: java permgen jmap

我正在尝试解决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

以下是我将如何解释上述输出 - 请更正我在此过程中所犯的任何错误。

“类型”列中的值不是唯一的。我们看到一些出现三次的物体。但是,class_loader值在所有三个中都是唯一的;因此,它们中的每一个都是一个独特的对象,占据了permgen空间。在这个例子中,每个占用100个字节;因此,SomeClassLoader类型的对象占用了300字节的permgen空间。

如果classes值为非零,则此对象必须是某种类的加载器,这指的是它引用的类的数量。 (注意:在实际文件中,这三个对象在bytes列中都有零;我为这个例子添加了值。在实际操作中,我猜测如果classes列中有0,那就没办法了bytes值可以是零。)

如果alive值为“dead”,则表示该对象已准备好进行垃圾回收,但JVM没有这样做。对于可能出现这种情况的原因,需要单独讨论。

如果parent_loader列中有一个值,那么这是另一个类加载器引用的对象,在该对象被垃圾回收之前不能进行垃圾回收。

最后: 1)如果我在报告中看到所有列出相同类型的500行, 2)但是它们列出了不同的class_loader值, 3)然后我可以在bytes列中添加值 4)这将准确地表示该类型的物体占据多少permgen空间。

这是对的吗?谢谢!

1 个答案:

答案 0 :(得分:6)

从此blog entry

  

对于每个类装入器对象,将打印以下详细信息:

     
      
  1. (class_loader)类加载器对象的地址 - 在运行实用程序时的快照中。
  2.   
  3. (classes)加载的类数(由此加载器使用方法(java.lang.ClassLoader.defineClass)定义。
  4.   
  5. (bytes)此类加载器加载的所有类的元数据消耗的大致字节数。
  6.   
  7. (parent_loader)父类加载器的地址(如果有)。
  8.   
  9. (活着?)“实时”或“死”指示 - 表示将来是否会对装载程序对象进行垃圾回收。
  10.   
  11. (type)此类加载器的类名。
  12.   

永久生成不包含普通对象,而是包含类元数据(请参阅What does PermGen actually stand for?)。所以,重写你的陈述:

  

最后:1)如果我在报告中看到所有列出相同类型的500行,2)但它们列出了不同的class_loader值,3)那么我可以在字节列4)中添加值,这将准确表示由同一个(SomeClassLoader)类的类加载器对象加载的所有类的元数据占用了多少permgen空间。

Eclipse Memory Analyzer工具显示的“保留堆”是指对象消耗的堆内存(年轻+旧)。

永久生成不在堆中(请参阅https://stackoverflow.com/a/12058171/33622)并处理类元数据