对象的建立

Java时一门面向对象的编程语言,在Java程序运行过程当中无时无刻都有对象被建立出来。那在虚拟机中对象如何而建立呢?程序员

  虚拟机遇到一条new指令时,将首先检查这个指令的参数可否子常量池中定位到一个类的符号引用,而且检查这个符号引用表明的类是否已被加载、解析和初始化过。若是没有,那就必须先执行相应地类加载过程。编程

  在类加载检查经过之后,虚拟机将为新生对象分配内存。对象所需内存大小在类加载完成后即可彻底肯定,为对象分配空间的任务等同于把一块肯定大小的内存从Java堆总划分出来。而内存划分又可分为两种方式。方式一、指针碰撞:假设Java堆中内存是绝对规整的,全部使用过的内存在一边,空闲的内存放在另外一边,中间有一个指针做为分界点的指示器,那么所分配内存就仅仅是把那个指针向空闲空间那边挪动与对象大小相等的一段距离。方式二、空闲列表:若是Java堆中的内存不是规整的,而是交错分布的,那就不能简单地进行指针碰撞来分配了,虚拟机就必须来维护一个列表,记录那些内存时可使用的,在分配的时候从列表总找到一块足够大的空间划分给对象,并更新列表上的记录。这两种方式的选取时根据Java堆是否规整来决定的,而Java堆是否规整又是由垃圾回收器是否带有压缩整理宫内来决定的。安全

  除了如何划分空间外,另外一个须要思考的问题是对象建立在虚拟机中是很是频繁的行为,即便仅仅修改一个指针的指向位置,在并发状况下也并非线程安全的,可能出现正给对象A分配内存,指正尚未修改,对象B又同时使用原来的指针来分配内存的状况。解决这个问题也有两种方案。一是对分配聂村空间的动做进行同步处理——实际是虚拟机采用CAS配以失败重试的方式来保证更新操做的原子性;另外一种是把内存分配的动做按照线程划分在不一样的空间之间进行,即每一个线程在Java堆中预先分配一块小内存,称为本地线程分配缓冲。线程分配内存时如今本地线程分配缓冲上分配,当本地线程分配缓冲用完并分配新的时才须要同步锁定。并发

  内存分配完成后,虚拟机须要将分配的内存都初始化为零值。这一步保证了对象的实例字段在Java代码中能够不赋初始值就直接使用,程序能访问到这些字段的数据类型锁对应的零值。编程语言

  以上工做完成后,在虚拟机来看,一个新的对象已经产生了 ,可是从Java程序角度来看,对象建立来看,对象建立才开始——init方法尚未执行,全部字段都还为零。因此,通常执行new指令以后会接着执行init方法,把对象按照程序员的意愿来进行初始化,这样一个真正可用的对象才算彻底产生出来。线程

相关文章
相关标签/搜索