当前位置: 首页 > 后端技术 > Java

JVM 新生代为什么要有两个 survivor(from, to) 区

时间:2023-04-01 13:53:31 Java

为什么JVM新生代有两个survivor(from,to)区域?,一次只使用其中一个。垃圾回收时,将正在使用的内存中存活的对象复制到另一个内存区域,然后清除正在使用的内存区域,交换两个区域的角色,完成垃圾回收。那为什么在新生代使用复制算法:因为新生代gc比较频繁,对象存活率低,用复制算法回收效率会更高,不会产生内存碎片。但是复制算法的代价是内存减半。为了不浪费太多内存,划分了两个大小相同的内存区survivorfrom和survivorto。每次GC后,会将幸存的对象复制给另一个幸存者,然后清除Eden和刚刚使用过的幸存者。上面的参考来自:https://www.zhihu.com/question/44929481/answer/98016105,上面的回答解释了为什么newgeneration在标记清除死对象后使用replication算法,而不是标记清除死对象后进行compactingobjectsDefragmentation消除内存碎片(这里的内存碎片就是死对象占用的空间)。新生代使用复制算法的缺陷在于,由于使用了复制算法,每次只能使用1/2的空间,可用内存空间变成1/2。由于2.中描述的缺陷,需要想办法优化复制算法中的可用内存空间>1/2。优化方法是将eden区:survivor区=1:1改为eden区:survivor区=8:2,这样可用内存空间就变成了8/10。但是这样一来,下一次YoungGC之后,存活的对象就会被移动到survivor区,而我们的可用区只有2/8,太小了。继续优化3.描述的问题,我们将新生代划分到eden区:survivor0(from):survivor1(to)=8:1:1,每次在eden区创建新生代对象,对象上次GC中幸存的from区,下一次GC要移动的对象是eden区和from区幸存的对象,被移动到to区,然后是from区和from区的标识到区域交换。这样我们新生代可用的内存空间就是9/10(eden+from)。上述解决方案的演变就是“为什么新一代JVM有两个survivor(from,to)区域”的原因。