对象的内存布局

对象的创建过程

class loading

class linking

class initializing

申请内存

成员变量赋默认值

调用构造方法

对象内存布局

可以分为两种:普通对象、数组对象

普通对象:

  1. 对象头:markword 8
  2. ClassPointer指针:-XX:+UseCompressedClassPointers 为4字节 不开启为8字节
  3. 实例数据:引用类型:-XX:+UseCompressedOops 为4字节 不开启为8字节 Oops Ordinary Object Pointers
  4. Padding对齐:8的倍数

数组对象:

  1. 对象头:markword 8
  2. ClassPointer指针:-XX:+UseCompressedClassPointers 为4字节 不开启为8字节
  3. 数组长度:4字节
  4. 数组数据
  5. Padding对齐:8的倍数

 一个Object对象的大小

    //一个Object占多少个字节
    // -XX:+UseCompressedClassPointers(关闭压缩) -XX:+UseCompressedOops(普通对象指针)
    // Oops = ordinary object pointers
    对象头8+class指针(默认把压缩指针打开,8个字节压缩成4个字节)+对齐4=16
    private static class P {
                        //8 _markword
                        //4 _class pointer
        int id;         //4
        String name;    //4 本来应该是8个字节,但是开启了-XX:+UseCompressedOops
        int age;        //4

        byte b1;        //1
        byte b2;        //1

        Object o;       //4 普通对象指针
        byte b3;        //1

    }

Hotspot开启内存压缩的规则(64位机)

  1. 4G以下,直接砍掉高32位

  2. 4G - 32G,默认开启内存压缩 ClassPointers Oops

  3. 32G,压缩无效,使用64位 内存并不是越大越好(^-^)

 Markword对象头

 

 不同状态下的markword是表示不同的内容的,这个不是固定的。

  • synchronized有一个锁升级的过程,其中偏向锁是用一位来表示偏向模式,下次这个线程再进来就不需要加锁,其实偏向锁是用三位来表示。
  • 对象的hashcode显示的前提是调用了未被重写hashcode()方法才会产生,重写过的hashcode方法计算的结果不会保存在这里。
  • 后面的JVM新生代在经过15次GC之后会变成老年代,为啥是15次?是因为分代年龄那里用4位来表示,1111最大为15.
  • 当一个对象计算过identityHashCode之后,不能进入偏向锁状态,因为偏向锁的那个位置被占

 对象定位 

  1. 句柄池
  2. 直接指针

 

 

 对象分配

  • 栈上分配,栈一弹出对象就没了
  • 栈不能分配,而且对象很大,分配到OLD区最后由FGC回收
  • 对象不大,看是否可以线程本地分配,不可以就分配到Eden区,GC到了一定的分代年龄之后进入OLD区,最后由FGC回收

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值