【发布时间】:2020-02-16 13:32:15
【问题描述】:
我正在尝试获取正在运行的 JVM 中某个类的所有实例的平均大小。我可以使用 jcmd 或类似工具创建堆转储,但这需要几秒钟,这是一个生产服务器,所以我宁愿有更快的东西。 jcmd 可以选择创建这种格式的直方图:
num #instances #bytes class name
----------------------------------------------
1: 84907 559415720 [I
2: 9572537 229740888 java.lang.String
3: 803323 142900392 [C
4: 3190710 102102720 java.util.Hashtable$Entry
这似乎很有希望,但我认为字节大小是浅的而不是保留的内存。有没有办法创建具有保留大小的相同直方图?或者是另一种快速获取类实例平均大小的方法?
我知道 GDB 方法,但它不适合,因为输入命令序列需要几秒钟,而这大约是使用 jcmd 进行堆转储所需的时间。
【问题讨论】:
-
假设您用 1 兆字节的文本填充
ArrayList<String>,然后用list2.addAll(list1);填充另一个列表。这两个列表的大小是多少?两种尺寸的总和是总尺寸吗?不,因为它们引用了相同的字符串。因此,不可能正确计算对象的大小。这在很大程度上取决于您要计算内存的哪些部分。