Java堆转储中统计信息的细分是什么

时间:2012-07-19 08:43:48

标签: java out-of-memory heap-dump

鉴于此堆转储

size         no. of obj class
515313696       2380602 char[]
75476832        614571  * ConstMethodKlass
57412368        2392182 java.lang.String
44255544        614571  * MethodKlass
33836872        70371   * ConstantPoolKlass
28034704        70371   * InstanceKlassKlass
26834392        349363  java.lang.Object[]
25853848        256925  java.util.HashMap$Entry[]
24224240        496587  * SymbolKlass
19627024        117963  byte[]
18963232        61583   * ConstantPoolCacheKlass
18373920        120113  int[]
15239352        634973  java.util.HashMap$Entry
11789056        92102   ph.com.my.class.Person

只有一个课程来自我的应用ph.com.my.class.Person。类定义如下:

public class Person {
 private String f_name;
 private String l_name;
}

在堆转储中,Person size (11789056)是否包含2个字符串变量占用的内存?或者f_namel_name是否会计入String类,在这种情况下,大小为57412368?

更新 - 添加后续问题:

所以让我们说每个实例:

  1. f_name大小为30
  2. l_name大小为20
  3. 人数为75
  4. 如果有10个Person实例,则会有

    1. 10 *(30 + 20)= 500
    2. 10 * 75 = 750
    3. 500会被计算在String还是char []?然后,750将被计入人物?

2 个答案:

答案 0 :(得分:2)

每个计数和大小都是该对象的大小。如果您使用-histo而不是-histo:live,这将是所有对象,甚至是未引用的对象。

注意:每个String都有一个char[],而JVM使用了其中的一小部分。 String大小是对象本身的大小,而不是其char[]

答案 1 :(得分:2)

堆转储中对象的大小是作为堆上的块分配的字节数,用于容纳该实例。它从不包括通过对象可到达的整个图形的字节。通常,这很容易意味着对象的大小是整个堆。因此,在您的情况下,它会考虑两个引用,但不考虑String实例本身。另请注意,即使String大小也不会反映所代表字符串的大小 - 它存储在char[]中。 char[]个实例在字符串之间共享,所以故事并不那么简单。