java虚拟机——对象的创建

原创 2016年08月28日 22:39:39

对象的创建

java是一种面向对象的语言,通常我们在创建对象时,大多是通过 "类名 变量名 = new 类名()" ,那么在底层的虚拟机中是怎么进行的呢?
(1)当虚拟机检测到一条new指令时,首先先检查当前创建的这个对象的类是否加载(通过方法区的常量池的符号引用来定位),如果这个类没有加载,则先去加载这个类(具体如何加载,我会在以后的章节继续写)。如果该类已经加载,则执行接下来的步骤。
(2)类加载后,便开始执行对象的创建,其实也就是为对象分配内存空间(一般在年轻代的Eden区进行分配,大对象直接进入老年代)。对象的所占大小在类加载后根据类中分区(在HotSpot虚拟机中对象的内存中有对象头,实际数据和对齐填充,具体接下来会讨论)便可知。
(3)在分配空间时虚拟机会根据不同情况采用不同方式:
1.指针碰撞:当java堆中的内存布局是绝对规整的,什么是绝对规整?就是所有存活的对象在堆区的一端,空闲的内存在另一端,那么在存活的对象和空闲空间的分隔点(临界点)放置了一个类似指针的指示器,当分配一个新对象的空间时,就是将指针向空闲空间方向移动和该对象大小相等的距离。
2.空闲列表:当java堆中的内存不是规整的,凌乱不堪,存活对象所占的内存和空闲内存相互交错,那么就不能使用指针碰撞的方法了。这时候虚拟机就必须需要一个列表来记录哪些位置的内存是空闲的,可以使用的,在创建对象的时候从列表中划分出一个足够大的空间给对象。
(4)那么问题来了,java堆什么时候是绝对规整的,什么时候相互交错的情况呢?
这就要由JVM的垃圾收集器来决定了。比如Serial收集器、ParNew收集器和Parallel Scavenge收集器等,在对内存进行一次回收后,便将堆内存压缩成存活对象一端、空闲内存另一端的规整情况(这几种属于年轻代的垃圾收集器,采用了复制算法)。采用空闲列表的情况,主要是由于虚拟机采用了类似于CMS这种收集器来进行回收内存,而CMS属于老年代的垃圾回收器,采用的是标记-清除算法
(5)但是现在又有一个问题出现了,如果在创建A对象时,指针(指示器)会改变位置,但此时对象B又同时正在创建,又使用了原来的指针,此时会出现线程不安全的情况,针对这种情况,JVM采用两种方式进行解决:
1.可能大家都会想到,使用同步进行处理。
2.使用本地线程分配缓存,简称TLAB(Thread Local Allocation Buffer),就是把分配内存的行为按照线程分别分配到各自之中进行,每个线程中预先在堆中分配一块空间,在线程创建对象,分配内存的时候,首先在缓存中进行分配,在缓存使用完时,使用同步进行新的TLAB的分配。
(6)在分配完内存之后,需要进行内存空间的初始化。这一步操作保证了我们在创建对象时,不需要像局部变量声明时那样必须指定初始值,可以直接使用对象中的成员变量。接下来虚拟机需要对对象进行一些必要的设置,比如:对象属于哪个类,HashCode,GC分代年龄等(这些信息都放在对象头)。
(7)在这之后,虚拟机已经将一个对象创建完成了,那么对于我们来说,仅仅一句话而已,对象才刚刚创建完成,所有字段都为各自类型的0值,所以一般在执行new指令之后就要执行<init>方法,将对象按照程序员的方式进行初始化。
至此,一个真正可用的对象创建完成。
接下来的章节会跟大家简单的讨论对象的内存布局和对象的访问方式。
如有错误,还望大家指正,谢谢

相关文章推荐

java虚拟机理解(一)——内存模型与对象创建

JVM是java语言一项重要产物,正是由于JVM的存在,才使得java语言的跨平台特性。闲话少说,先来总结一下java虚拟机的内存模型。1) 再说java内存模型      运行时数据区域通常分为:方...
  • cai2016
  • cai2016
  • 2017年03月21日 13:53
  • 189

Java虚拟机(四)——对象的创建、存储和定位

对象的创建  Java是一门面向对象的编程语言,Java 程序运行过程中无时无刻都有对象被创建出来,在语言层面上,创建对象(例如克隆,反序列化)通常仅仅是一个new关键字而已,例如下面的语句。Obje...

深入理解java虚拟机——判断对象的“死活”

深入理解java虚拟机——判断对象是否存活 在第三章中,讲诉垃圾算法之前,需要明确一件事,即:哪些对象可以算作是“垃圾”,从而被回收。...

java虚拟机——对象的布局、访问方式

对象的内存布局 在上一章节中,我们讨论了对象在虚拟机中是如何创建的,那么在对象创建后,它在内存中是如何进行布局的呢?也就是说它都有哪些区域和内容呢? 对象在内存中的布局可以分为3个区域:对象头、实...
  • Mr_fsd
  • Mr_fsd
  • 2016年08月28日 23:39
  • 235

java虚拟机学习笔记——类型和对象的生命周期(第七章)

概述 这一章以一个Java类型(类或接口)的生命周期为例来讨论开始阶段的装载、连接和初始化,以及占Java类型生命周期绝大部分时间的对象实例化、垃圾收集和对象终结,然后是java类型生命周期的结束,...
  • FG2006
  • FG2006
  • 2011年08月20日 03:13
  • 1448

java虚拟机理解(二)——对象访问机制

接着说java虚拟机,对象创建结束后需要使用对象,就涉及到对对象访问的问题。虚拟机的取指指针在栈上获取对象引用后,就需要到堆上去获取对象实例。对象访问取决于虚拟机实现。主流的java虚拟机采用直接指针...
  • cai2016
  • cai2016
  • 2017年03月22日 19:52
  • 217

【003】【Java虚拟机——对象已死判定】

垃圾收集器在对堆进行回收前,首先要做的事情就是要确定这些对象之中哪些还“存活”着, 哪些已经“死去" (即不可能再被任何途径使用的对象)。...

Java虚拟机(HotSpot)-对象:创建、内存布局、访问定位

《深入理解Java虚拟机》第2版-第二章读书笔记 对象的创建1.检查这个指令的参数是否能在常量池中定位到这个类的符号引用,如果存在即进入22.检测该符号引用代表的类是否已被加载、解析和初始化过,若没有...
  • name_z
  • name_z
  • 2016年10月04日 10:54
  • 284

<Java虚拟机>读书记录2-对象的创建

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

深入理解java虚拟机 第2章(二):对象创建,内存布局,访问

java对象的创建java对象创建,内存布局,访问定位
  • Scplove
  • Scplove
  • 2016年09月06日 03:26
  • 415
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java虚拟机——对象的创建
举报原因:
原因补充:

(最多只允许输入30个字)