Java垃圾收集对年轻对象使用复制收集器。年轻一代区域分为“伊甸园空间”和两个幸存者空间,s0和s1。
我知道复制收集器从伊甸园和一个幸存者空间复制幸存的物体到另一个幸存者空间。
从概念上讲,2个空间应该足够了,将幸存者从一个空间复制到另一个空间。我假设Java使用3个空格而不只是2个空格的原因是,新对象总是可以在相同的位置创建,在伊甸园区域。
问题是,为什么在伊甸园区域创建新的(年轻空间)对象很重要,而不是在“复制到”幸存空间中的最后一个复制对象之后创建?
发布于 2019-09-20 00:14:49
您提出的替代方案有两个大小相等的新空间,并从一个空间复制到另一个空间。您会发现,当新空间(总)的一半被填满时,您需要运行新一代GC。
在Oracle GC使用的方法中,(通常) Eden size > S1 size + S2 size,在运行新一代GC时,您已经填满了所有的Eden +部分S1 (或S2)。这将大大超过总新空间内存的一半。换句话说,新的空间内存得到了更有效的利用。
这份Oracle培训材料有一些很好的图表,解释了新一代GC和旧一代GC期间发生的事情:
但请注意,本教程描述的是一个简化的分代收集器。不同版本的Java所支持的各种实际收集器的细节有很大的不同。
发布于 2019-09-20 04:42:27
对于G1,只有一个幸存空间(尽管为了兼容性,JVM报告存在两个空间)。
有了G1收集器,所有的堆都是单池的,“功能”空间是完全动态的。因此,幸存空间仅分配给收集(并在收集完成后成为伊甸园的一部分。
JVM中支持的大多数其他收集器都要求“功能”空间具有静态边界,这些边界是在HotSpot启动时定义的。因此,空的幸存者空间不能成为伊甸园的一部分。
https://stackoverflow.com/questions/58014748
复制相似问题