JVM学习笔记(二)对象创建

对象创建过程

对象的创建

Java是一门面向对象的语言,Java程序运行过程中无时无刻都有对象被创建出来。在语言层面上,创建对象仅仅是一个new关键字而已。而在虚拟机中,对象(限于普通Java对象,不包括数据和Class对象等)的创建又是怎样一个过程呢?
JVM学习笔记(二)对象创建

当Java虚拟机遇到一个new关键字时,首先检查常量池中是否含有该对象,并且检查这个符号代表的类是否已被加载、解析和初始化过。如果没有,必须要先执行相应的类加载过程。
在类检查通过后,接下来虚拟机要为对象分配内存。分配内存有两种方式,假设Java堆中的内存是绝对规整的,所有被用过的内存放在一边,没有使用的放在一边,用一个指针分割,当为对象分配内存时,只需要根据对象需要内存的大小把指针移位,这种分配方式称为“指针碰撞”。如果内存是碎片化的,虚拟机必须维护一张表,记录哪些内存是可用的。在分配过程中找到足够大的连续内存区域,并更新列表上的记录,这种分配方式称为“空闲列表”。Java堆的内存空间规整与否和垃圾回收机制有关。
除了如何规划内存空间分配以外,还需要考虑并发带来的不安全问题。可能内存正在给线程A分配内存,指针还没来的及修改,此时B线程也使用了原指针分配内存,就会出现A对象被覆盖的问题。此时有两种解决方式,第一种用CAS配上失败重试的方式保证原子性,另外一种是为每个线程预先分配一小块内存,成为本地线程分配缓存,为线程分配内存时首先使用本地缓冲区分配,如果缓冲区用完,才需要使新的缓存区加同步锁定。
内存分配完之后,虚拟机必须将分配的内存空间(但不包括对象头)都初始化为零值
接下来,Java虚拟机还要对对象进行必要的设置,例如对象是那个类的实例、如何能够找到类的元数据、对象的哈希码、对象GC等信息。
在上面的步骤完成之后,Java虚拟机的角度来看,一个对象已经创建好了。但是从Java程序出发,对象创建才刚刚开始,初始化方法还没有执行,所有的字段都默认的零值。需要执行init()方法,按照程序员的意愿对对象初始化,这样一个真正可用的对象才算完全被构造出来。