4

鉴于此堆转储

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

我的应用程序中只有 1 节课,ph.com.my.class.Person. 类定义如下:

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

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

更新 - 添加了后续问题:

所以让我们说每个实例:

  1. f_name 大小为 30
  2. l_name 大小为 20
  3. 人的大小是75

如果有10个Person实例,就会有

  1. 10 * (30+20) = 500
  2. 10 * 75 = 750

500 将计入 String 或 char[] 吗?随后,750 人是否会被计算在内?

4

2 回答 2

2

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

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

于 2012-07-19T09:02:03.693 回答
2

堆转储中对象的大小是在堆上分配为块以保存该实例的字节数。它从不包括可通过对象访问的整个图形的字节。一般来说,这很容易意味着对象的大小是整个堆。因此,在您的情况下,它考虑了两个引用,但不考虑 String 实例本身。另请注意,即使String大小也不能反映所表示字符串的大小——它存储在char[]. 这些char[]实例在字符串之间共享,所以故事并不那么简单。

于 2012-07-19T09:02:33.703 回答