hashcode
对象头中的mark word存储对象运行时信息,如Hash Code、Age(对象的年龄)、锁状态标识、线程持有的锁、偏向线程ID、偏向时间戳等。
知识准备:
场景1 – 调用hashCode(),对象头才有hashCode值:
public class Test {
public static void main(String[] args) {
A a = new A();
//jvm的信息
System.out.println(VM.current().details());
System.out.println("-------------------------");
//打印a对象的hashcode值
System.out.println(Integer.toHexString(a.hashCode()));
//以表格的形式打印对象布局
System.out.println(ClassLayout.parseInstance(a).toPrintable());
}
}
注意:
为什么打印出来的hashcode值在对象头中是逆序的?
–采用的是小端存储,小端存储是从后往前存;大端存储是从前往后存。
–一旦调用hashcode方法,锁的状态一定不再是偏向状态。
java内存,大端小端判断
大端模式:是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址端。
小端模式,是指数据的高字节保存在内存的高地址中,低位字节保存在在内存的低地址端。
//Java中,存放此long类型数据,实际存放占8个字节,01,02,03,04,05,06,07,08
// 01是高位字节,08是最小低位字节
byte b = UNSAFE.getByte(a);
//通过getByte方法获取刚才存放的long,取第一个字节
//如果是大端,long类型顺序存放—》01,02,03,04,05,06,07,08 ,取第一位便是0x01
//如果是小端,long类型顺序存放—》08,07,06,05,04,03,02,01 ,取第一位便是0x08
什么是高字节:
在十进制中我们都说靠左边的是高位,靠右边的是低位,在其他进制也是如此。
就拿 0x12345678来说,从高位到低位的字节依次是0x12、0x34、0x56和0x78。
场景2 – 不调用hashCode(),对象头没有hashCode值:
public class Test {
public static void main(String[] args) {
A a = new A();
//jvm的信息
System.out.println(VM.current().details());
System.out.println("-------------------------");
System.out.println(ClassLayout.parseInstance(a).toPrintable());
}
}