0.背景
看jvm源码的时候,不禁会想:
- java程序中打印对象堆内存地址,和debug jvm时观测到的一样吗,怎么取得这些值?
- 对象成员变量在内存中如何布局,遵从定义顺序吗,Unsafe::objectFieldOffset获取的是什么,又是怎么实现的呢?
- 上述实现跟类的加载解析是如何关联的?
- 有类继承关系,有静态变量是会如何?
源码及环境参考:jdk8u,64位系统
1.打印对象内存布局1 2
先来点感性认识,已经有很好的工具实现了这个功能:Java Object Layout (JOL)3
1.1 测试对象类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class SimpleInt {
private int state;
}
class SimpleLong extends SimpleInt {
private char state;
}
class FieldsArrangement extends SimpleLong {
private boolean first;
private char second;
private double third;
private int fourth;
private boolean fifth;
private static int si;
}
public static Unsafe getUnsafe() throws NoSuchFieldException, IllegalAccessException {
Field f = Unsafe.class.getDeclaredField("theUnsafe"); //Internal reference
f.setAccessible(true);
return (Unsafe) f.get(null);
}
1.2 测试类
1
2
3
4
5
// -XX:-UseCompressedOops 为避免不必要麻烦,后面测试代码类同
public static void main(String args[]) throws Exception {
FieldsArrangement fa = new FieldsArrangement();
System.out.println(ClassLayout.parseInstance(fa).toPrintable());
}
输出结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
oop.FieldsArrangement object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 8 (object header: class) 0x0000000112224848
16 4 int SimpleInt.state 0
20 4 (alignment/padding gap)
24 2 char SimpleLong.state