[英]Memory allocation in G1 GC
据我所知,当使用G1时,GC会被分割成一组大小相等的堆区域。
JVM如何在区域中分配新对象? 选择哪个区域进行分配?
我想多个Edens的原因是它们是线程本地的。 像这样的东西很可能也被其他收藏家使用,因为分配需要很快并且处理共享变量很慢并且规模很大。 当这样的Eden耗尽时,需要一些同步才能获得一大块VM。
IIUIC G1在选择要收集的区域方面有所不同,而不是如何分配区域。
来自Oracle Docs :
堆被分区为一组大小相等的堆区域,每个区域都是一个连续的虚拟内存区域。 某些区域集具有与旧收集器中相同的角色(eden,survivor,old),但它们没有固定的大小。 这为内存使用提供了更大的灵活性。
以下是原始垃圾收集研究论文关于分配的内容:
堆区域中的分配包括在分配和未分配空间之间递增边界顶部 。 一个区域是分配存储的当前分配区域 。 由于我们主要关注多处理器,因此mutator线程使用比较和交换或CAS操作直接在此堆区域中分配线程局部分配缓冲区或TLAB 。 然后,他们在这些缓冲区中私下分配对象,以最大限度地减少分配争用。 当填充当前分配区域时,选择新的分配区域。 空区域被组织成链表以使区域分配成为恒定时间操作。
一般来说,你需要意识到G1仍然是 世代垃圾收集器 。 因此,这意味着对象分配发生在通常情况下的Young Generation(Eden空间)中。 从这个角度来看,G1没有什么新东西。 G1和例如CMS之间的区别在于Young Gen被分成几个大小相等的区域。
Eden区域是在世界停留时收集的,并且对象被压缩到To空间中 ,因此将这些对象分配到不同的Eden区域并不是真正的问题。
堆积如山的对象分配发生在堆积如山的地区-这是分配一个大对象的特殊情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.