JAVA中对象

  1. 对象内存布局(HotSpot)

  2. 概述

  3. 布局划分为三部分:对象头(Header)、实例数据(Instance)、对齐填充(Padding)
  4. 对象头包含两类信息:用于存储对象自身的运行时数据(Mark Word)和对象指向它的类型元数据的指针(类型指针)
  5. 实例数据部分时对象真正存储的有效信息,存储顺序受JVM分配策略参数和字段在java源码中定义顺序的影响,
  6. HotSpot默认存储顺序:long/double,int,short,char,byte/boolean,oop(Ordinary Object Pointer)
  7. 对齐填充部分不是必须存在,也没有任何含义,仅仅用于占位符

     

  8. 对象头(Header)

  9. 对象自身的运行时数据(Mark Word)
  10. 这部分数据的长度在32位和64位的未开启压缩指针的JVM中分别为32bit和64bit。
  11. Mark Word是一个有着动态定义的数据结构,目的在于在极小的空间存储更多的数据,根据对象的状态复用自己的存储空间
  12. 32位HotSpot中,如果对象未被同步锁锁定的状态下,Mark Word的32bit存储空间中,25bit用于存储对象哈希码,4bit存储对象分代年龄,2bit存储锁标志位,1bit固定为0。其他状态存储内容如下表

     

    锁状态

    25bit

    4bit

    1bit

    2bit

    23bit

    2bit

    是否偏向锁

    锁标志位

    无锁

    对象的HashCode

    分代年龄

    0

    01

    偏向锁

    线程ID

    Epoch

    分代年龄

    1

    01

    轻量级锁

    指向栈中锁记录的指针

    00

    重量级锁

    指向重量级锁的指针

    10

    GC标记

    11

     

  13. 类型指针
  14. JVM通过这个指针来确定该对象是哪个类型的实例
  15. 并不是所有JVM实现都必须在对象数据上保留类型指针。
  16. 如果对象是数组,对象头中还必须有一块用于记录数组长度的数据

     

  17. New对象()

  18. JVM创建对象过程

     

  19. 对象查找

  20. 概述

  21. reference类型在JVM规范中只规定了它是一个指向对象的引用,并没有定义这个引用应该通过什么方式去定位、访问到堆中对象的具体位置
  22. 主流访问方式有:使用句柄和直接指针

     

  23. 通过句柄访问

  24. JVM将在队中划分除一块内存作为句柄池,reference中存储对象的句柄地址,而句柄包含了对象实例和类型数据各自的地址信息
  25. 优势是:reference存储的是稳定句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而本身不用被修改

  26. 通过直接指针访问

  27. 堆中的内存布局必须考虑如何放置访问类型数据的相关信息,reference存储的就是对象地址
  28. 访问对象本身,不需要多一次间接访问开销,相对句柄,速度块,节省了一次指针定位的时间开销
  29. Hotspot主要使用此方法访问

posted @ 2020-05-31 22:28  adeveloper  阅读(271)  评论(0编辑  收藏  举报