以编程方式计算Java对象占用的内存,包括它引用的对象

Kis*_*nan 18 java memory-management

我需要以编程方式确切地找出给定Java对象占用的内存量,包括它引用的对象所占用的内存.

我可以生成内存堆转储并使用工具分析结果.但是,生成堆转储需要花费大量时间,并且需要这样的工具来读取转储以生成报告.鉴于我可能需要多次这样做,如果我可以在我的项目中输入一些能够给我这个值"运行时"的代码,那么我的工作会更灵活.

我怎么能最好地实现这个目标?

ps:具体来说,我有一个javax.xml.transform.Templates类型的对象集合

Var*_*han 11

你需要使用反射.由此产生的代码对于我来说太复杂了(尽管它很快将作为我正在构建的GPL工具包的一部分提供),但主要的想法是:

  • 对象头使用8个字节(用于类指针和引用计数)
  • 每个原始字段使用1,2,4或8个字节,具体取决于实际类型
  • 每个对象引用(即非原始)字段使用4个字节(引用,加上引用的对象使用的任何内容)

您需要单独处理数组(8个字节的标头,4个字节的长度字段,4个*长度的表字节,以及内部使用的任何对象).您需要使用反射处理迭代字段(以及它的父字段)的其他类型的对象.

您还需要在递归期间保留一组"看到"的对象,以便不要多次计算多个位置引用的对象.

  • 对于它的价值,对象头至少使用了那么多,但我认为较旧的JVM使用更多.通过简单的测试代码(创建一百万个对象,gc,睡眠一点,检查可用内存 - 理论上保证不起作用,在实践中)也很容易(足够)验证. (2认同)
  • 另外:4个字节用于32位引用.对于64位系统,我认为是8个字节. (2认同)

Rob*_*bin 6

看起来已经有一个名为Classmexer的实用工具.

我自己没有尝试过,但是在我推出自己的路线之前,我会走那条路.