G1 GC中的内存分配

4
据我所知,当使用G1 GC时,堆被分成一组等大小的堆区域。
JVM如何在这些区域中分配新对象?哪个区域被选用进行分配?
3个回答

2

我猜Eden区域之所以有多个,是因为它们是线程本地的。其他收集器很可能也使用类似的机制,因为分配需要快速处理,而共享变量的处理速度慢且扩展性差。当这样的Eden区耗尽时,需要进行一些同步操作,以获取新的VM块。

在我的理解中,G1与其他收集器的不同之处在于它选择要收集的区域的方式,而不是在分配方面有所不同。


1
Oracle Docs中获取的内容:

enter image description here

堆被划分为一组等大小的堆区域,每个区域都是一个连续的虚拟内存范围。某些区域集被分配了与旧收集器相同的角色(eden、survivor、old),但它们的大小并不固定。这提供了更大的内存使用灵活性。
还请参阅垃圾优先垃圾收集器调优

但是当分配新对象时,它将被放置在伊甸园区的哪个位置? - Costa Mirkin
1
@Costa Mirkin:这有何关系?你如何区分这些区域?你期望什么样的答案,“从左边数第三个”吗? - Holger
1
某个区域是否填满直到末尾,然后在新区域中分配对象,或者分配可以在不同的伊甸园区域中执行? - Costa Mirkin

1

以下是原始的垃圾优先垃圾收集研究论文中关于分配的内容:

在堆区域中分配是通过增加已分配和未分配空间之间的边界top来完成的。一个区域是当前分配区域,从该区域分配存储。由于我们主要关心多处理器,因此变异者线程仅直接在此堆区域中分配线程本地分配缓冲区(TLABs),或称为线程专用对象栏,使用比较并交换或CAS操作。然后他们在这些缓冲区内私下分配对象,以最小化分配争用。当当前分配区域填满时,选择新的分配区域。将空区域组织成链接列表,以使区域分配成为常量时间操作。

总的来说,您需要意识到G1仍然是一种分代垃圾收集器。这意味着通常情况下对象分配发生在年轻代(伊甸园区)。从这个角度来看,G1并没有什么新的东西。 G1和CMS等之间的区别在于,年轻代被分成几个大小相等的区域。 伊甸园区停顿式暂停收集的区域,对象被压缩到To空间中,因此在不同的伊甸园区分配这些对象并不是真正的问题。 庞大对象分配发生在庞大区域 - 这是大对象的特殊情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接