对象创建

  • 类加载过后可以直接确定一个对象的大小
  • 对象栈上分配是通过逃逸分析判定、标量替换实现的,即把不存在逃逸的对象拆散,将成员变量恢复到基本类型,直接在栈上创建若干个成员变量
  • 选择哪种分配方式由Java堆是否规整决定,而Java堆是否规整又由所采用的垃圾收集器是否带有压缩整理 功能决定。因此,在使用Serial、ParNew等带Compact过程的收集器时,系统采用的分配算法是指针碰撞,而使用 CMS这种基于Mark-Sweep算法的收集器时,通常采用空闲列表
  • 空间并发分配解决方案
    • TLAB,线程私有空间分配,只有TLAB用完并分配新的TLAB时,才需要同步锁定
    • CAS+失败重试保证更新操作的原子性

对象内存布局

内存布局

  • Klass Word(类指针):存储对象的类型指针,该指针指向它的类元数据。从JDK 1.6 update14开始,64位的JVM正式支持了-XX:+UseCompressedOops(默认开启),可以压缩指针,起到节约内存占用的作用。oop(ordinary object pointer)即普通对象指针,下列指针将压缩至32位:

    • 每个Class的属性指针(静态成员变量)
    • 每个对象的属性指针(对象变量)
    • 普通对象数组的每个元素指针
  • 指针压缩:

    • 如果GC堆大小在4G以下,直接砍掉高32位,避免了编码解码过程(偏移量除以/乘以8)
    • 如果GC堆大小在4G以上32G以下,则启用-XX:+UseCompressedOops命令
    • 如果GC堆大小大于32G,压指失效,使用原来的64位
  • -XX:+UseCompressedClassPointers

    • Java8使用Metaspace存储元数据,开启后类元信息中的指针也用32bit的Compressed版本,即Klass Word
    • 依赖-XX:+UseCompressedOops
  • 数组长度64位JVM的情况下也被压缩至32位

  • 对齐字节:HotSpot VM的自动内存管理要求对象大小必须是8字节的整数倍,不足时需要对齐填充来补全

对象头

  • 32位虚拟机占用32个字节,不同状态下各个比特位区间大小有变化

  • biased_lock:偏向锁标记,为1时表示对象启用偏向锁

  • age:默认情况下,并行GC的年龄阈值为15,并发GC的年龄阈值为6。由于age只有4位,所以最大值为15

  • identity_hashcode

    • 采用延迟加载技术,只有在需要时使用System.identityHashCode(Object x)计算后写到该对象头中
    • 偏向锁没有存储HashCode的地方,偏向锁期间调用System.identityHashCode(x)会造成锁升级
    • 轻量级锁和重量级锁所指向的lock record或monitor都有存储HashCode的空间
    • 用户自定义hashCode()方法所返回的值不存在Mark Word中,只针对identity hash code
  • thread:持有偏向锁的线程ID

  • epoch:偏向锁的时间戳

  • ptr_to_lock_record:轻量级锁状态下,指向栈中锁记录的指针

  • ptr_to_heavyweight_monitor:重量级锁状态下,指向对象监视器Monitor的指针

ClassLayout

// 引入依赖
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.11</version>
</dependency> // 查看对象布局信息
ClassLayout layout = ClassLayout.parseInstance(new A());
System.out.println(layout.toPrintable());

可通过ClassLayout查看对象布局信息,即对象占用空间情况

对象访问定位

句柄访问对象 直接指针访问对象
  • 句柄访问:java堆中会划分一块内存作为句柄池,线程栈中引用中存储的就是对象句柄地址。好处在于对象句柄地址固定,对象移动(垃圾回收时移动对象非常普遍)时仅改变句柄中的实例数据指针
  • 直接指针访问:线程栈中引用中存储的直接就是对象地址,好处在于速度更快(Sun HotSpot使用此种)

JVM之对象创建、对象内存布局、对象访问定位的更多相关文章

  1. 浅谈Java虚拟机内存中的对象创建,内存布局,访问定位

    参考于 深入理解Java虚拟机 这里介绍HotSpot虚拟机(自带的虚拟机) 1.对象的创建 对于程序员来说,创建对象的方法: User user1 = new User(); User user2 ...

  2. Java对象的创建、内存布局和访问定位

    在Java运行时数据区中,我们知道了虚拟机内存的概况,本文介绍虚拟机内存中的数据的其它细节,如对象如何创建.如何布局以及如何访问. 基于实用的原则,这里以HotSpot虚拟机和常用的内存区域Java堆 ...

  3. JVM 专题十二:运行时数据区(七)对象的实例化内存布局与访问定位

    1. 对象的实例化 1.1 创建对象的方式 new 最常见的方式 变形1 : Xxx的静态方法 变形2 : XxBuilder/XxoxFactory的静态方法 Class的newInstance() ...

  4. JVM运行时数据区--纵向补充--对象的实例化内存布局与访问定位

    对象的实例化 创建对象的方式 1.new:最常见的方式(本质是构造器) 变形1 : Xxx的静态方法 变形2 : XxBuilder/XxoxFactory的静态方法 2.Class的newInsta ...

  5. 【深入理解JVM】:Java对象的创建、内存布局、访问定位

    对象的创建 一个简单的创建对象语句Clazz instance = new Clazz();包含的主要过程包括了类加载检查.对象分配内存.并发处理.内存空间初始化.对象设置.执行ini方法等. 主要流 ...

  6. 深入理解java虚拟机(二)HotSpot Java对象创建,内存布局以及访问方式

    内存中对象的创建.对象的结构以及访问方式. 一.对象的创建 在语言层面上,对象的创建只不过是一个new关键字而已,那么在虚拟机中又是一个怎样的过程呢? (一)判断类是否加载.虚拟机遇到一条new指令的 ...

  7. HotSpot Java对象创建,内存布局以及访问方式

    内存中对象的创建.对象的结构以及访问方式. 一.对象的创建 在语言层面上,对象的创建只不过是一个new关键字而已,那么在虚拟机中又是一个怎样的过程呢? (一)判断类是否加载.虚拟机遇到一条new指令的 ...

  8. java面试-对象的创建、内存布局、访问定位

    一.对象的创建 1.虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载.解析和初始化过.如果没有,那必须先执行相应的 ...

  9. 深入理解Java虚拟机(二)、Java对象的创建,内存布局和访问定位

    对象的创建: Object obj = new Object(); 常量池中是否有Ljava.lang.Object

  10. 【JVM之内存与垃圾回收篇】对象实例化内存布局与访问定位

    对象实例化内存布局与访问定位 从各自具体的内存分配上来讲 new 的对象放在堆中 对象所属的类型信息是放在方法区的 方法当中的局部变量放在栈空间 这 new 的对象怎么把三块粘合到一起 就是这章的内容 ...

随机推荐

  1. P1337 [JSOI2004]平衡点(模拟退火)题解

    题意: 如图:有n个重物,每个重物系在一条足够长的绳子上.每条绳子自上而下穿过桌面上的洞,然后系在一起.图中X处就是公共的绳结.假设绳子是完全弹性的(不会造成能量损失),桌子足够高(因而重物不会垂到地 ...

  2. Gym 101170F Free Weights(二分)题解

    题意:给出两行,每一行都有n个数组,一共有2 * n个,大小为1~n,每个有两个.现在可以进行操作:拿出一个物品i,然后放到一个空格,花费i.可以任意平移物品,平移没有花费.每一行空间无限.要求你把一 ...

  3. git push bug

    git push bug fast-forwards $ git push $ git push --help # git pull $ gp To http://git.xgqfrms.xyz:88 ...

  4. ES6 version repeatify

    ES6 version repeatify String.prototype.repeatify = String.prototype.repeatify || function (times = 1 ...

  5. 使用 js 实现十大排序算法: 基数排序

    使用 js 实现十大排序算法: 基数排序 基数排序 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

  6. Android Activity 与 WebView 页面线程不一致 bug​

    Android Activity 与 WebView 页面线程不一致 bug​ refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

  7. taro scroll tabs 滚动标签 切换

    taro scroll tabs 滚动标签 切换 https://www.cnblogs.com/lml-lml/p/10954069.html https://developers.weixin.q ...

  8. Python学习笔记_有关tuple的几点强调

    创建只有一个元素的tuple,需要用逗号结尾消除歧义 a_tuple = (2,) tuple中的list mixed_tuple = (1, 2, ['a', 'b']) print("m ...

  9. JDK源码阅读-FileOutputStream

    本文转载自JDK源码阅读-FileOutputStream 导语 FileOutputStream用户打开文件并获取输出流. 打开文件 public FileOutputStream(File fil ...

  10. springboot学习过程随记

    1.整合shiro+jwt(若忘记需结合测试代码springboot-mybatisplus-shiro-demo看) 配置比较简单 定义一个类继承AuthorizingRealm 如下: (1)pu ...