目录

一、对象的实例化

对象创建的几种方式

对象创建的步骤

二、对象的内存布局

三、对象的访问定位

JVM是如何通过栈帧中的对象引用访问到其内部的对象实例呢?

1.句柄访问

2.直接指针(HotSpot采用这种方式)


一、对象的实例化

对象创建的几种方式

1.new关键字。

(1)直接new Xxx()

(2)调用Xxx的静态方法,返回一个新建的对象。

(3)XxxBuilder/XxxFactory使用工厂模式获取对象。

2.Class的newInstance():反射的方式,只能调用空参构造器,权限必须是public,jdk9标记为该方法为已过时。

3.Constructor的newInstance(Xxx):反射的方式,可以调用空参、带参的构造器,权限没有要求。

4.使用clone():不调用任何构造器,当前类需要实现Cloneable接口,实现clone()。

5.使用反序列化:从文件中、从网络中获取一个对象的二进制流。

6.第三方库Objenesis。

对象创建的步骤

①.从字节码角度看:

反编译java -p -v xxx.class

②.从执行步骤看:

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

虚拟机遇到一条new指令,首先去检查这个指令的参数能否在Metaspace的常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化。(即判断类元信息是否存在)。如果没有,那么在双亲委派模式下,使用当前类加载器以ClassLoader+包名+类名为Key进行查找对应的.class文件。如果没有找到文件,则抛出ClassNotFountException异常,如果找到,则进行类加载,并生成对应的Class类对象。

2.为对象分配内存。

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

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

(2)分配堆空间,如果内存规整——指针碰撞。

如果内存是规整的,那么虚拟机将采用的是指针碰撞法(Bump The Pointer)来为对象分配内存。

意思是所有用过的内存在一边,空闲的内存在另一边,中间放着一个指针作为分界点的指示器,分配内存就仅仅是把指针指向空闲那边挪动一段与对象大小相等的距离罢了。如果垃圾收集器选择的是Serial、ParNew这种基于压缩算法的(内存会进行整理,内存比较规整),虚拟机采用这种分配方式。一般使用带有compact(整理)过程的收集器时,使用指针碰撞。

(3)分配堆空间,如果内存不规整——虚拟机需要维护一个列表,空闲列表分配.

如果内存不是规整的,已使用的内存和未使用的内存相互交错,那么虚拟机将采用的是空闲列表法来为对象分配内存。

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

(4)说明

选择哪种分配方式由Java堆是否规整决定,而Java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。

3.处理并发安全问题

(1)采用CAS失败重试、区域加锁保证更新的原子性

(2)每个线程预先分配一块TLAB——通过-XX:+/-UseTLAB参数来设定是否开启TLAB

4.初始化分配到的空间——所有属性设置默认值,保证对象实例字段在不赋值时可以直接使用

5.设置对象的对象头

将对象的所属类(即类的元数据信息)、对象的HashCode和对象的GC信息、锁信息等数据存储在对象的对象头中。这个过程的具体设置方式取决于JVM实现。

6.执行init方法进行初始化(调用代码块、构造器进行初始化)

在Java程序的视角来看,初始化才正式开始。初始化成员变量,执行实例化代码块,调用类的构造方法,并把堆内存对象的首地址赋值给引用变量。

因此一般来说(由字节码中是否根锁有invokespecial指令所决定),new指令之后会接着就是执行方法,把对象按照程序员的意愿进行初始化,这样一个真正可用的对象才算完全创建出来。

二、对象的内存布局

1.对象头。包含两部分:

(1)运行时元数据(Mark Word)

哈希值(HashCode)

GC分代年龄

锁状态标志

线程持有的锁

偏向线程ID

偏向时间戳

(2)类型指针——指向类元数据的InstanceKlass,确定该对象所属的类型。

说明:如果是数组,还要记录数组的长度。

2.实例数据(Instance Data)

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

规则:(1)相同宽度的字段总是被分配在一起。(2)父类中定义的变量会出现在子类之前。(3)如果CompactFields参数为true(默认为true),子类的窄变量可能插入到父类变量的空隙。

3.对其填充(Padding)——不是必须的,也没特别含义,仅仅起到占位符的作用。

4.小结:图示举例

三、对象的访问定位

JVM是如何通过栈帧中的对象引用访问到其内部的对象实例呢?

答:定位,通过栈上reference访问(有两种方式)。

1.句柄访问

优点:reference中存储稳定句柄地址,对象被移动(垃圾收集时移动对象很普遍)时只会改变句柄中实例数据指针即可,reference本身不需要被修改。

缺点:还要单独开辟一块句柄池,作为“中间商”

2.直接指针(HotSpot采用这种方式)

优缺点与句柄访问相反

对象创建的过程细节是怎样的?一起来探讨内存变化细节相关推荐

  1. (1)访问控制 (2)final关键字 (3)对象创建的过程 (4)多态

    1.访问控制(笔试题) 1.1 常用的访问控制符 public - 公有的 protected - 保护的 啥也不写 - 默认的 private - 私有的 1.2 访问控制符的比较 访问控制符 访问 ...

  2. Java对象创建的过程及对象的内存布局与访问定位

    这里以HotSpot为例,且所说的对象指普通的Java对象,不包括数组和Class对象等. 1.对象创建的过程 1.类加载.解析.初始化:虚拟机遇到new时先检查此指令的参数是否能在常量池中找到类的符 ...

  3. JAVA构造器及对象创建的过程

    今天学妹问我Java对象到底是怎么创建的?那我必须要从底层给学妹讲清楚呀! 一. 构造器 JAVA中构造器也称为构造方法,它用于对象的初始化. 构造器分为: 无参构造器 有参构造器 构造器的一些特点: ...

  4. 对象创建的过程 java_Java 对象创建过程

    构造器是静态方法. 1. Java中,用new()创建一个对象的时候,Java虚拟机首先去检查new指令的参数是否能够在方法区的常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否被加载. ...

  5. 指令级别解释对象创建过程和DCL为什么要volatile

    先上图 先明白几点 1.jvm stack指的是线程栈,一个线程有一个jvm stack. 2.线程里的一个方法对应一个栈帧,一个栈帧有Local Variables(本地变量表,记录了方法的参数.局 ...

  6. 对象创建过程 流程解析图 详细之极

    我们在学的时候,不仅要知其然,还要知其所以然! 所以今天我能总结了一张关于对象创建整体过程流程图.其中包括了 1.对象的创建过程 2.类的加载过程 3.每个类加载过程的讲解 4.类加载器的简单介绍 总 ...

  7. 百无聊赖之JavaEE从入门到放弃(五)this的本质_对象创建过程的4 步_隐式参数 static

    目录 一.this关键字 1.对象创建的过程和this的本质 2.this最常的用法: 二.static关键字 三.变量分类 一.this关键字 1.对象创建的过程和this的本质 构造方法是创建Ja ...

  8. MyBatis运行原理(二)SqlSession对象创建过程分析

    PS:这篇博文承接上一篇: MyBatis运行原理(一)SqlSessionFactory对象创建过程分析 在上一篇博文中分析了SqlSessionFactory对象创建的过程,有了SqlSessio ...

  9. MyBatis运行原理(一)SqlSessionFactory对象创建过程分析

    一.写在前面 MyBatis基于接口形式的编程主要步骤: 1.创建SqlSessionFactory对象. 2.根据SqlSessionFactory对象获取SqlSession对象. 3.为mapp ...

最新文章

  1. mybatis关系映射(1对1,1对多,多对多)
  2. WORD2010自动编号后,目录那里编号和文字中间有很大的空格,怎么
  3. TS Interface
  4. linux怎么设置屏显示同步,linux设置同步时间
  5. gm(GraphicsMagick)图片中文水印乱码问题
  6. 美国广告市场:Facebook和Google将占据四分之一市场份额
  7. php获取总共内存_PHP获取内存使用情况详解
  8. String与StringBuilder区别总结
  9. Ubuntu 16.04 安装VNC服务端
  10. Java项目开发案例全程实录_SSM项目全程实录(完整实战开发附源码)
  11. cnode系列之登陆注册功能
  12. 波特率和比特率之间的关系
  13. C# WPF 3DTools下的TrackballDecorator清除view,出现Null异常
  14. 嵌入式硬件上电后,程序的运行过程剖析(CPU、FLASH、内存)
  15. 将FTP空间通过网络映射到本地电脑上
  16. Excel制作图表(二)--- 燃尽图
  17. iOS 开发AVFoundation系统原生二维码扫描实现
  18. 谈谈用户体验与风控的平衡性
  19. Tampermonkey谷歌浏览器插件
  20. 路由器的类型及衡量路由器性能的主要参数指标

热门文章

  1. 引用类型的转换 java,java中引用类型的强制转换
  2. created写法_在vue中created、mounted等方法使用小结
  3. centos7添加运行终端快键键
  4. java实现混合运算_java图形化界面实现简单混合运算计算器
  5. java 字符串 面试_Java 字符串面试题
  6. java虚成员函数_Java常见知识点汇总(④)——虚函数、抽象函数、抽象类、接口...
  7. caxa明细表导入零件材质_各种橡胶材质橡胶制品
  8. mplayer-php,jQuery MPlayer网站音乐播放器插件
  9. androidstudio自动生成变量_使Eclipse或AndroidStudio的代码模板自动生成类名和方法名...
  10. android 弹窗圆角,Android 自定义底部圆角弹窗的实现