为何垃圾回收的年轻代需划分Eden、From、To三个区域?
嘿,这个问题问得特别戳点——你说的双区域复制回收逻辑完全站得住脚,理论上确实能完成垃圾回收,但JVM里额外加个Eden区,本质是基于年轻代对象存活规律的效率优化,咱们掰开了说:
利用对象“朝生夕死”的特性,减少无效复制
年轻代里90%以上的新对象活不过第一次GC,如果把所有新对象都放进两个复制区域里,每次GC都要把这些很快就会被回收的对象复制一遍,这纯粹是浪费CPU和内存带宽。Eden区就是专门装这些短命对象的:新对象优先存在Eden,只有Eden满了才触发Minor GC,只把Eden里存活的对象复制到其中一个Survivor区(From/To),大部分垃圾直接在Eden里被清理,根本不用走复制流程,省了大量不必要的开销。大幅提升空间利用率
如果只用两个区域做复制回收,每次只能用一半的空间存对象(因为另一半必须空出来接收复制的存活对象)。但加了Eden之后,Survivor区只需要占很小的比例(比如HotSpot默认比例是Eden:From:To=8:1:1),相当于年轻代90%的空间都能用来存新对象,只有10%的空间用来做复制周转。举个例子:年轻代总大小100M,双区域模式下只能用50M存对象;而Eden+双Survivor模式下,能用到80+1=81M的空间,空间利用率提升非常明显。减少存活对象的复制次数
存活下来的对象会在From和To两个Survivor区之间来回复制,每复制一次年龄就加1,达到阈值后晋升到老年代。如果没有Eden区,所有对象(包括那些很快就死的)都会进入复制流程,而Eden区相当于一个“过滤器”,只让真正存活的对象进入Survivor区,大大减少了需要复制的对象数量和次数。
简单说:双区域复制是可行的,但Eden区是JVM针对年轻代对象的实际存活规律做的优化,让GC更高效、空间使用更划算。
内容的提问来源于stack exchange,提问作者Bonsaisteak

