可除了TLAB以外,虚拟机为了保证对象的原子性所采用的的另外一种方式不是CAS+失败重试吗?
时间: 2024-03-30 13:39:25 浏览: 52
是的,虚拟机为了保证对象的原子性,除了 TLAB 以外,还可以采用 CAS + 失败重试的方式来实现。在使用 CAS 进行对象创建时,虚拟机会将对象头中的 Mark Word 当做期望值,然后使用 CAS 尝试将其更新为新的对象头。如果 CAS 操作失败,说明有其他线程已经修改了对象头,这时候虚拟机会重新分配一块新的内存,然后再次尝试 CAS 操作,直到操作成功为止。
使用 CAS + 失败重试的方式可以避免使用锁所带来的性能开销,但是失败重试的次数可能会比较多,从而导致性能问题。因此,在实际应用中,需要根据具体情况来选择使用 TLAB 还是 CAS + 失败重试来保证对象的原子性。
相关问题
NEW时,如果发现符号引用代表的类没有进行类加载,会先执行对应的类加载。 类加载执行完后给对象分配内存,内存的分配有两种方式分别是指针碰撞和空闲列表, 用哪种取决于使用的垃圾回收器是否具备空间整理能力,有Compact能力的回收器用的是指针碰撞没有的则是空闲列表。 为了保证多线程环境下对象分配内存的原子性,默认情况下虚拟机采用CAS算法加失败重试来保证原子性,还有一种方法是给每一个线程都分配一块TLAB内存空间。 内存分配完成后,虚拟机会对堆内存空间内实例对象的成员变量进行零值初始化,如果之前用的是TLAB的话, 零值初始化也可以在TLAB给对象分配内存时进行。这样在Java代码中可以不给字段赋与初始值就使用字段。 然后虚拟机会给对象设置一个对象头,里面存放有一些信息。 最后会执行对象的构造方法进行初始化。是否正确
您的理解是正确的。当执行`new`关键字时,如果虚拟机发现符号引用代表的类没有进行类加载,会先执行对应的类加载,然后再进行内存分配。内存分配有两种方式,分别是指针碰撞和空闲列表。使用哪种方式取决于使用的垃圾回收器是否具备空间整理能力。如果垃圾回收器具备空间整理能力,就使用指针碰撞。否则,就使用空闲列表。
为了保证多线程环境下对象分配内存的原子性,默认情况下虚拟机采用CAS算法加失败重试来保证原子性。另外,还有一种方法是给每个线程分配一块TLAB内存空间。内存分配完成后,虚拟机会对堆内存空间内实例对象的成员变量进行零值初始化。如果之前使用的是TLAB,零值初始化也可以在TLAB给对象分配内存时进行。这样,在Java代码中可以不给字段赋与初始值就使用字段。最后,虚拟机会给对象设置一个对象头,里面存放有一些信息。最后执行构造方法进行初始化。
阅读全文