HostSpot 虚拟机对象布局
1.java 对象布局
Java对象分为:对象头、实例数据、对齐填充组合。
对齐填充:
对齐填充并不是必然存在的,也没有特定的含义,仅仅起着占位符的作用。由于HotSpot虚拟机的自动内存管理系统要求对象的起始地址必须是8字节的整数倍,也就是对象的大小必须是8字节的整数倍。而对象头部分正好是8字节的倍数(1倍或者2倍),因此,当对象实例数据部分没有对齐的时候,就需要通过对齐填充来补全。对象字节数/8的倍数,如果不足的话 实现填充。例如:一个对象21个字节,则需要补充3个字节。
实例数据:对象中定义的成员属性。
对象头:
固定的大小。32位系统对象头大小为8个字节、64位系统对象头大小为16个字节。
HotSpot虚拟机的对象头(Object Header)包括两部分信息:
第一部分"Mark Word":用于存储对象自身的运行时数据, 如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等.
第二部分"Klass Pointer":对象指向它的类的元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。(数组,对象头中还必须有一块用于记录数组长度的数据,因为虚拟机可以通过普通Java对象的元数据信息确定Java对象的大小,但是从数组的元数据中无法确定数组的大小。 )

注意:在64位的虚拟机情况下 mark word 占用64位 ,32位虚拟机占32位。
64位等于多少 /8 8个字节

虚拟机源码中查看Mark Word:

KClass Pointer:
这一部分用于存储对象的类型指针,该指针指向它的类元数据,jvm通过这个指针确定对象是哪个类的实例。该指针的位长度为JVM的一个字大小,即32位的JVM为32位,64位的JVM为64位。
如果应用的对象过多,使用64位的指针将浪费大量内存,统计而言,64的JVM将会比32位的JVM多耗费50的内存。为了节约内存可以使用选项 -XX:+UseCompressedOops 开启指针压缩。其中 oop即ordinary object pointer 普通对象指针。
如果在64位操作系统下,如果对象头字节为12个字节,说明是java虚拟机对对象头进行了压缩。
对象头压缩设置:
-XX:+UseCompressedOops 开启指针压缩
-XX:-UseCompressedOops 不开启指针压缩
对象头:Mark Word+Klass Pointer类型指针 未开启压缩的情况下
32位 Mark Word =4bytes ,类型指针 4bytes ,对象头=8bytes =64bits
64位 Mark Word =8bytes ,类型指针 8bytes ,对象头=16bytes=128bits;
注意:默认情况下,开启了指针压缩 可能只有12字节。
new出一个对象对象头占多少个字节:
如果是32位操作系统对象头占8个字节,如果是64位操作系统对象头占16个字节(没有被压缩的情况下)。
占用字节=对象头+实例数据+对齐填充/8

java 打印对象头信息所需Maven依赖:
org.openjdk.jol 
jol-core 
0.10 
java 代码实现:对象为 int 类型
public class UserEntity {
    private int a;
    public static void main(String[] args) {
        UserEntity userEntity = new UserEntity();
        // 打印对象头信息
        System.out.println(ClassLayout.parseInstance(userEntity).toPrintable());
    }
}
控制台打印结果:
com.example.test.UserEntity object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           80 30 d1 1b (10000000 00110000 11010001 00011011) (466694272)
     12     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
     16     4    int UserEntity.a                              0
     20     4        (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes totaljava 代码实现:对象为 Interger 类型
public class UserEntity {
    private Integer a;
    public static void main(String[] args) {
        UserEntity userEntity = new UserEntity();
        // 打印对象头信息
        System.out.println(ClassLayout.parseInstance(userEntity).toPrintable());
    }
}
控制台打印结果:
com.example.test.UserEntity object internals:
 OFFSET  SIZE                TYPE DESCRIPTION                               VALUE
      0     4                     (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4                     (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4                     (object header)                           80 30 1c 1c (10000000 00110000 00011100 00011100) (471609472)
     12     4                     (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
     16     8   java.lang.Integer UserEntity.a                              null
Instance size: 24 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes totalInteger包装类型会对int类型自动的进行填充,由4变成了8,能够被8整除。
打印 对象hashcode位置:
public class UserEntity {
    private int a;
    public static void main(String[] args) {
        UserEntity userEntity = new UserEntity();
        // 打印 hashCode 所在位置
        System.out.println(Integer.toHexString(userEntity.hashCode()));
        // 打印对象头信息
        System.out.println(ClassLayout.parseInstance(userEntity).toPrintable());
    }
}
控制台输出:
5b2133b1
com.example.test.UserEntity object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 b1 33 21 (00000001 10110001 00110011 00100001) (557035777)
      4     4        (object header)                           5b 00 00 00 (01011011 00000000 00000000 00000000) (91)
      8     4        (object header)                           00 31 4f 1c (00000000 00110001 01001111 00011100) (474951936)
     12     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
     16     4    int UserEntity.a                              0
     20     4        (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total基本数据类型占多少字节
1、bit --位:位是计算机中存储数据的最小单位,指二进制数中的一个位数,其值为“0”或“1”。
2、byte --字节:字节是计算机存储容量的基本单位,一个字节由8位二进制数组成。在计算机内部,一个字节可以表示一个数据,也可以表示一个英文字母,两个字节可以表示一个汉字。
64位/8
1Byte=8bit (1B=8bit)
1KB=1024Byte(字节)=8*1024bit
1MB=1024KB
1GB=1024MB
1TB=1024GB
int 32bit 4
short 16bit 2
long 64bit 8
byte 8bit
char 16bit
float 32bit
double 64bit
boolean 1bit
    
    
    










