JVM 里 new 对象时,堆会发生抢占吗?JVM 是怎么设计来保证线程安全的?

当多个线程同时进行对象的内存分配时,可能会出现指针抢占的问题。假设在JVM虚拟机上,每次进行对象分配时,指针会向右移动一个对象大小的距离。当一个线程正在为对象A分配内存时,指针尚未更新。同时,另一个线程也需要为对象B分配内存,并使用了同一个指针进行分配,这就发生了抢占现象。

为了解决这个问题,有两种可选方案:

  1. 使用CAS(Compare and Swap)分配重试的方式来保证更新操作的原子性。通过CAS操作,每个线程尝试将指针向右移动一个对象大小的距离,并更新指针的值。如果CAS操作失败,表示有其他线程已经修改了指针的值,那么当前线程需要重新尝试分配内存,直到成功为止。
  2. 每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB)。当线程需要分配内存时,首先在自己的本地缓冲区中进行分配。只有当本地缓冲区用完时,才需要进行同步锁定来分配新的缓冲区。这种方式可以减少线程间的竞争和同步开销,提高内存分配的效率。

标签: java, Java面试题, Java问题合集, Java编程, Java问题精选, Java常见问题