1. TLAB。最快,最频繁的方式。
TLAB是伊甸园中保留给线程本地分配的区域。每个线程可以创建许多TLAB:一旦一个线程被填充,就会使用#2中描述的技术创建一个新的TLAB。即,创建新的TLAB就像在Eden中直接分配大型元对象。
每个Java线程都有两个指针:
tlab_top和
tlab_limit。TLAB中的分配只是指针增量。由于指针是线程本地的,因此不需要同步。
if (tlab_top + object_size <= tlab_limit) { new_object_address = tlab_top; tlab_top += object_size;}-XX:+UseTLAB默认情况下启用。如果将其关闭,则对象将在Eden中分配,如下所述。
2.在伊甸园(年轻一代)的分配。
如果TLAB中没有足够的空间用于新对象,则创建新的TLAB或直接在Eden中分配对象(取决于TLAB废物限制和其他人体工程学参数)。
在Eden中的分配类似于在TLAB中的分配。还有两个指针:
eden_top和
eden_end,它们对于整个JVM是全局的。分配也是指针增量,但是由于所有线程之间都共享Eden空间,因此使用原子操作。通过使用特定于体系结构的原子指令来实现线程安全:CAS(例如,
LOCK CMPXCHG在x86上)或LL / SC(在ARM上)。
3.在老一代中分配。
这取决于GC算法,例如CMS使用空闲列表。老一代中的分配通常仅由垃圾收集器本身执行,因此它知道如何同步自己的线程(通常与分配缓冲区,无锁原子操作和互斥锁的混合)。



