【问题标题】:How to interpret the output from "jmap -permstat"?如何解释“jmap -permstat”的输出?
【发布时间】:2012-11-02 04:33:29
【问题描述】:

我正在尝试对 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 个字节;因此,SomeClassLoader 类型的对象占用了 300 字节的 permgen 空间。

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

如果存活值为“dead”,则表示对象已准备好进行垃圾回收,但 JVM 并未这样做。关于为什么会出现这种情况的原因需要单独讨论。

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

最后: 1) 如果我在报告中看到 500 行都列出了相同的类型, 2) 但它们列出了不同的 class_loader 值, 3)然后我可以将字节列中的值相加 4) 这将准确地表示该类型的对象占用了多少永久空间。

这是正确的吗?谢谢!

【问题讨论】:

  • 我应该注意:我在这里要求澄清的原因是因为如果我假设我的问题的最后两段是正确的,那么 jmap 报告一个特定的类占用了数百兆字节的 permgen;而如果我得到一个堆转储并使用 Eclipse 内存分析器工具搜索相同的类,它会显示 25 兆字节的“保留堆”大小。我对 jmap 或 EMAT 的理解存在差距。

标签: java permgen jmap


【解决方案1】:

来自blog entry

对于每个类加载器对象,打印以下详细信息:

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

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

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

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

永久生成在堆之外(参见https://stackoverflow.com/a/12058171/33622)并处理类元数据

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-04
    • 2014-08-09
    • 2021-06-01
    • 2014-02-03
    • 2018-09-16
    • 2018-09-09
    • 1970-01-01
    • 2015-11-11
    相关资源
    最近更新 更多