对象创建过程

来源:互联网 发布:激光切割机软件 编辑:程序博客网 时间:2024/06/10 08:22

对象的创建过程:
1.指令参数能否在常量池中定位到一个类的符号引用;
2.检查这个符号引用代表的类是否已经被加载、解析和初始化,如果没有必须先执行类加载过程;
3.类加载检查通过后,虚拟机分配内存(对象的内存大小在类加载完成后就可以确定)。内存分配有“指针碰撞”和“空闲列表”两种方式。
首先先解释一下“指针碰撞”–假设java堆内存是绝对完整的,那么用过的内存放在一边,空闲的内存放在一边,中间放着一个指针作为
分界点指示器,那么分配内存的时候就是把指针向空闲内存那边挪动对象大小等距离的位置。
“空闲列表”是指java堆的内存是不规整的,已使用的内存和空闲内存是交叉存在的,那就没有办法简单的进行“指针碰撞”了,
虚拟机就需要维护一个列表,这个列表上记录了那些内存是可用的,在分配时从列表对象中划分一块足够大的空间划分给对象实例,并更新表上的实例。
java堆是否规则是由所采用的gc是否带有压缩整理功能决定的。
4.除了划分可用空间外,还需考虑对象创建在虚拟机中是否频繁出现,因为在并发环境下即使仅仅修改一个指针所指向的位置也不是线程安全的
例如我正在给A对象分配内存,指针还没来得及修改,对象B又使用了原来的指针)。
两种解决方案:一、对分配内存空间的动作进行同步处理–实际上就是虚拟机采用CAS配上失败重试的方式保证更新操作的原子性;
二、把内存分配动作划分给不同空间执行,即每个线程在java堆中预先分配一小块内存,称为本地线程分配缓冲。哪个线程要分配内存,
就在哪个线程的TLAB上分配,只有TLAB用完并重新分配新的TLAB时,才需要同步锁定。可以使用-XX:+/-UserTLAB参数来设定。
5.内存分配完成后,虚拟机需要将分配到的内存初始化为零值(不包括对象头),如果使用TLAB,这一工作需要提前至TLAB分配时进行。
这一操作保证了对象实例字段可以在java代码中不赋初始值直接使用,程序能访问到这些字段所对应的零值。
6.**接下来需要一些必要的设置,例如这个对象时哪个类的实例、如何才能找到元数据信息、对象的哈希吗、对象的GC分代年龄等信息。
这些信息都存放在对象的对象头之中。**
7.上面工作完成后,从虚拟机视角来看,一个新的对象已经产生,但从java程序的视角来看,对象创建才刚刚开始–方法还没执行,所有字段都还是零。
一般来说执行new之后戒指执行方法,把对象按照程员的意愿进行初始化,这样一个真正的可用对象才算完全产生出来。

原创粉丝点击