对象的内存布局和访问定位

对象的实例化

对象的创建方式

  1. new

  2. Class的newInstance方法

    Class> aClass = Class.forName("com.mu.ConstructorDemo");ConstructorDemo o = (ConstructorDemo)aClass.newInstance();
  3. Constructor的newInstance方法,可以放参数,调用有参构造

    Constructor constructor = ConstructorDemo.class.getConstructor();ConstructorDemo constructorDemo = constructor.newInstance();
  4. Clone:不调用构造方法,当前类实现Cloneable接口

  5. 反序列化

创建对象的步骤

  1. 判断对象对应的类是否加载,链接,初始化

    虚拟机遇到一个new指令,首先去检查这个指令的参数能否在Metaspace的常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已经被加载,解析和初始化。

    如果没有,那么在双亲委派模式下,使用当前的类加载器,以ClassLoader+包名+类名为key进行查找对应的.class文件,如果没有找到文件,则抛出ClassNotFoundException异常,如果找到,则进行类加载,并生成对应的Class类对象

  2. 为对象分配内存

    首先计算对象占用空间大小,接着在堆中划分一块内存给新对象

    如果实例成员变量是引用变量,仅分配引用变量即可,即4个字节大小

  • 如果内存规整,使用指针碰撞

    所有用过的内存在一边,空闲的内存在另一边,中间放着一个指针作为分界点的指示器,分配内存就仅仅把指针向空闲那边挪动一段与对象大小相等的距离

    有压缩算法和整理功能的垃圾回收器,采用指针碰撞的方式分配内存

  • 如果内存不规整,虚拟机维护一个列表,使用空闲列表分配(CMS垃圾收集器)

    意思是虚拟机维护一个列表,记录那些内存块是可用的,再分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的内容,这种分配方式称为“空闲列表”

处理并发安全问题

创建对象是非常频繁的操作,虚拟机需要解决并发安全问题,两种方式:

  • CAS(Compare And Swap)失败重试,区域加锁,保证指针更新操作的原子性

  • TLAB:本地线程缓冲区

初始化分配到的空间

内存分配结束,虚拟机将分配到的内存都初始化成零值(不包括对象头),这一步保证了对象的实例字段在Java代码中可以不用赋值就可以使用,程序访问的都是这些字段的零值

设置对象头

将对象的所属类(类的元数据信息),对象的HashCode和对象的GC信息,锁信息等存储在对象的对象头中,这一块具体有JVM实现

执行init方法进行初始化

显式赋值

对象的内存布局

  1. 对象头

    包含两部分:

    如果是数组,还需要记录数组的长度

  • 运行时元数据

    哈希值,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳

  • 类型指针

    指向类元数据,确定该对象所属的类型

实例数据

它是对象真正存储有效信息,包括程序代码中定义的各种类型的字段(包括从父类继承下来的和自己拥有的)

相同宽度的字段分配在一起(比如4个字节的数据在一起)

父类定义的变量会出现在子类之前

如果CompactFields参数为true(默认是true),子类的窄变量可能插入到父类的变量的间隙

对齐填充

仅仅起到占位符的作用

package com.mu;public class Customer {public int id = 1001;    String name;    Account acct;    {        name = "匿名客户";    }public Customer(){        acct = new Account();    }public static void main(String[] args) {        Customer cust = new Customer();    }}class Account{

}

实际分配图如下:

对象的访问定位:

访问对象的方式有两种:句柄和直接指针

  1. 句柄访问

    图示:

    有一个句柄池的概念,栈指向句柄池,句柄池保存对象的实例数据和对象的类型数据

    优点是栈到句柄池的地址不会改变,reference存储的是稳定的句柄地址,在对象被移动时(垃圾回收时)只会改变句柄中到实例数据的指针

  2. 直接指针(Hotspot采用直接指针)

reference存储的就是对象的引用地址,最大的好处就是速度快,节省了一次指针定位的开销,

对象实例化指针_JVM第三课:一文讲透对象的内存布局和访问方式相关推荐

  1. 第 10 章 对象的实例化内存布局与访问定位

    第 10 章 对象的实例化内存布局与访问定位 1.对象的实例化 大厂面试题 美团: 对象在JVM中是怎么存储的? 对象头信息里面有哪些东西? 蚂蚁金服: 二面:java对象头里有什么 对象实例化 1. ...

  2. 7. 重磅硬核 | 一文聊透对象在JVM中的内存布局,以及内存对齐和压缩指针的原理及应用

    重磅硬核 | 一文聊透对象在JVM中的内存布局,以及内存对齐和压缩指针的原理及应用 大家好,我是bin,又到了每周我们见面的时刻了,我的公众号在1月10号那天发布了第一篇文章?<从内核角度看IO ...

  3. JVM---对象的实例化内存布局与访问定位

    对象的实例化内存布局与访问定位 面试题 对象在JVM中是怎么存储的? 对象头信息里面有哪些东西? Java对象头有什么? 从对象创建的方式和步骤开始: 对象创建的方式 new:最常见的方式.单例类中调 ...

  4. 10-对象实例化、内存布局与访问定位

    对象实例化内存布局与访问定位 对象实例化 面试题 对象在JVM中是怎么存储的? 对象头信息里面有哪些东西? Java对象头有什么? 从对象创建的方式 和 步骤开始说 对象创建方式 new:最常见的方式 ...

  5. java 句柄池_深入理解JVM之Java对象的创建、内存布局、访问定位详解

    本文实例讲述了深入理解JVM之Java对象的创建.内存布局.访问定位.分享给大家供大家参考,具体如下: 对象的创建 一个简单的创建对象语句Clazz instance = new Clazz();包含 ...

  6. 对象实例化指针_new一个对象发生了什么

    运行时数据区 闲言少叙,直接进入正题.这篇是跟java内存管理相关的,那么首先来概览一下java运行时内存数据区域划分. 这是一张经典的图了,下面简单介绍一下各区域都放哪些东西. 方法区:对于C++工 ...

  7. JVM:对象的实例化、内存布局与访问定位

    对象的实例化 创建对象的方式 new关键字 最常见的方式 变形1:Xxx的静态方法(单例模式) 变形2:XxxBuilder/XxxFactory的静态方法 Class的newInstance() 反 ...

  8. 0x00000000指令引用的内存不能为written_JVM03——对象实例化,内存布局,访问定位...

    从字节码角度看对象的创建过程 public class ObjectTest { public static void main(String[] args) { Object obj = new O ...

  9. java对象实例化内存布局与访问定位

    文章目录 1. 对象实例化方式 2. 对象创建的步骤 3. 对象的内存布局 4. 对象的访问定位 1. 对象实例化方式 通过new的方式,例如 Persion p = new Persion() 通过 ...

最新文章

  1. 快手数据中台建设实践
  2. 疯狂ios讲义疯狂连载之显示动画
  3. 用silverlight做动画-相机
  4. 【PC工具】200416最终百度网盘——最终下载方法及注意事项,代理是什么
  5. 干式双离合和湿式双离合的优缺点
  6. 杠件受力分析 第一章 杠件受力分析
  7. 前端学习(1306):node.js模块的加载机制
  8. 又见黑科技!量子薄膜传感器或推动VR设备变革
  9. python训练过程是什么_学了这么久,你知道Python机器学习全流程是怎样的么?
  10. 洛谷 P2894 酒店 Hotel
  11. Android 动画
  12. 集成DC电源RS485/422收发器数字隔离芯片CA-IS309X
  13. 2023CS保研经验分享(清深、上交、港科大、南大LAMDA、同济、东南Palm等)
  14. 特教学校计算机课,特教学校引入编程课 为听障孩子打开智能之门
  15. 玉米社:百度竞价推广否词什么意思?在哪里查看?怎么添加?【全】
  16. 严格模式 Strict Mode,与ES2020同步
  17. 硬派健身——健身先健脑
  18. [分享]来自CSDN的精华网址
  19. 火爆全网的动态曲线图是怎么做的?
  20. 计算机u盘病毒清除方式,U盘如何格式化和清理病毒

热门文章

  1. TensorFlow学习笔记(三)模型的基本步骤
  2. docker镜像、容器以及命令操作
  3. Tomcat源码解析三:tomcat的启动过程
  4. Java_Freemarker
  5. win7远程桌面连接不上,解决办法
  6. PHP单引号和双引号的区别
  7. [安卓] 7、页面跳转和Intent简单用法
  8. linux下ftp服务阶段实验(3)
  9. 从EXCEL文件将数据导入数据库的向导程序设计!
  10. 删除重复记录处理(转)