You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中ObjectGraphMeasurer.measure结果转字节方法及术语咨询

嘿,我来帮你拆解这个Caliper的Footprint结果,一步步搞清楚这些指标和内存计算方式:

先搞懂Footprint里的关键指标

咱们先把每个字段的含义理清楚:

  • Objects:你的对象图中包含的所有Java对象总数(比如各种POJO、集合、数组对象都算在内)。
  • NonNullRefs:所有对象里指向其他非null对象的引用数量——简单说就是对象之间有效的关联,比如一个ArrayList里的每个非null元素,就是一个NonNullRef。
  • NullRefs:对象中声明为引用类型但实际是null的字段数量——比如类里定义了String username但没赋值,这个空字段就会被统计成一个NullRef。
  • Primitives:对象图里所有基本类型的实例统计,后面的数字是对应类型的总数量(比如int x 388091就是有388091个int类型的值)。

把Footprint转换为总字节数的计算方法

要算出实际内存占用,得结合JVM的内存模型(这里以64位JVM开启指针压缩为默认情况,这是现代JVM的主流配置):

步骤1:计算基本类型的总字节数

每种基本类型的字节大小是固定的,直接相乘求和就行:

  • int:4字节 → 388091 × 4 = 1552364 字节
  • double:8字节 → 4375548 × 8 = 35004384 字节
  • long:8字节 → 2609976 × 8 = 20879808 字节
  • boolean:1字节(JVM中单个boolean字段占1字节,数组里的boolean也是1字节/元素)→ 6398 × 1 = 6398 字节
  • float:4字节 → 76765 × 4 = 307060 字节
  • char:2字节 → 66658 × 2 = 133316 字节

把这些加起来,基本类型总字节数是:1552364 + 35004384 + 20879808 + 6398 + 307060 + 133316 = 57883330 字节(约55.2MB)

步骤2:计算引用类型的总字节数

NonNullRefs + NullRefs 就是所有对象中引用类型字段的总数。在开启指针压缩的64位JVM中,每个引用字段占4字节;如果未开启指针压缩,每个引用占8字节。

以开启指针压缩为例:
总引用字段字节数 = (353968 + 1016731) × 4 = 1370699 × 4 = 5482796 字节(约5.23MB)

步骤3:计算所有对象的对象头总字节数

每个Java对象都有对象头,开启指针压缩时对象头是12字节,未开启是16字节。这里的对象数量就是Footprint里的Objects=270813:

开启指针压缩时:270813 × 12 = 3249756 字节(约3.1MB)

步骤4:加上对象对齐的开销

Java对象的大小必须是8字节的倍数,所以每个对象的实际大小会向上取整到最近的8字节。这部分开销很难精确计算(因为每个对象的字段数量不同),但通常可以估算为总对象大小的10%左右。

把前面三步的结果加起来,得到的近似值是:57883330 + 5482796 + 3249756 = 66615882 字节(约63.5MB),加上对齐开销后总内存大概在64-65MB之间。

更省心的方法:直接用Caliper的measureBytes

其实你不用手动计算这么麻烦,Caliper的ObjectGraphMeasurer提供了measureBytes(Object obj)方法,它会直接返回对象图的总内存占用字节数,已经自动考虑了对象头、对齐、指针压缩等所有细节,结果更准确。

示例代码:

long totalMemory = ObjectGraphMeasurer.measureBytes(yourTargetObject);
System.out.println("Total memory footprint: " + totalMemory + " bytes");

内容的提问来源于stack exchange,提问作者sarah hamza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:30:33