4

据我了解,在使用 G1 GC 时,堆被划分为一组大小相等的堆区域。
JVM 如何在区域中分配新对象?选择哪个区域进行分配?

4

3 回答 3

2

我想多个伊甸园的原因是它们是线程本地的。这样的东西很可能也被其他收集器使用,因为分配需要快速并且处理共享变量很慢并且扩展性很差。当这样的 Eden 耗尽时,需要进行一些同步才能获得新的 VM 块。

IUIC G1 的不同之处在于它如何选择要收集的区域,而不是它如何分配。

于 2013-11-06T19:54:33.670 回答
1

来自Oracle 文档

在此处输入图像描述

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

还要检查垃圾优先垃圾收集器调整

于 2013-11-06T19:01:21.163 回答
1

以下是最初的Garbage-First 垃圾收集研究论文中关于分配的内容:

堆区域中的分配包括增加已分配空间和未分配空间之间的边界top 。一个区域是从中分配存储的当前分配区域。由于我们主要关注多处理器,mutator 线程使用比较和交换或 CAS 操作直接在此堆区域中分配线程本地分配缓冲区TLAB 。然后他们在这些缓冲区中私下分配对象,以尽量减少分配争用。当当前分配区域被填满时,将选择一个新的分配区域。空区域被组织成一个链表,使区域分配成为一个常数时间的操作。

一般来说,您需要意识到G1仍然是分代垃圾收集器。因此,这意味着通常情况下对象分配发生在年轻代(伊甸园空间)中。从这个角度来看,G1并没有什么新鲜事。G1 和例如 CMS 之间的区别在于 Young Gen 被分成几个大小相等的区域。

Eden 区域在 stop-the-world 暂停中被收集,并且对象被压缩到 To 空间中,因此将这些对象分配到不同的 Eden 区域中并不是真正的问题。

巨大的对象分配发生在巨大的区域中——这是大型对象分配的一种特殊情况。

于 2013-11-06T22:38:14.733 回答