当虚拟机遇到一条new指令时,会去检查方法区检查是否已经在此类的数据(类已经被加载解析和初始化),不存在则 加载类数据。然后再堆上创建对象。这时,对象的创建一定会有多线程的问题,因为我们不知道某块内存地址,是否会同时有多个对象的创建。这时候一定是需要进行同步处理的。
下面说下对象创建的两种方式。
1:指针碰撞
假设堆内存是整齐有序的,指针一侧是已使用内存,另一侧是未使用内存,直接将指针移动对象的大小即可。(适用于有标记整理垃圾回收算法的JVM)
2:空闲列表
记录堆内存的空闲情况,并在合适的内存上创建对象,然后将此内存标记为已使用。(适用于CMS等基于mark-sweep的收集器)
关于同步:
1.使用cas+失败重试
2.使用TLAB,类似于ThreadLocal的思想,在堆上分配线程分配缓冲区(TLAB),每个线程都在自己的TLAB上分配对象,不存在冲突的情况,只有当TLAB用完时,才使用锁定。