共计 885 个字符,预计需要花费 3 分钟才能阅读完成。
先附一段对新生代中复制算法较好的了解:
首先得明确复制算法的思维:
将原有的内存空间划分成两块,每次只应用其中一块,在垃圾回收的时候,将正在应用的内存中的存活对象复制到另一块内存区域中,而后革除正应用过的内存区域,替换两个区域的角色,实现垃圾回收。而后为什么要在新生代中应用复制算法:
因为新生代 gc 比拟频繁、对象存活率低,用复制算法在回收时的效率会更高,也不会产生内存碎片。但复制算法的代价就是要将内存折半,为了不节约过多的内存,就划分了两块雷同大小的内存区域 survivor
from 和 survivor to。在每次 gc 后就会把存活对象给复制到另一个 survivor 上,而后清空 Eden 和刚应用过的 survivor。
以上援用自:https://www.zhihu.com/question/44929481/answer/98016105,上述答复解释了:
- 为什么新生代要在标记革除死亡对象后应用复制算法,而不是标记革除死亡对象后进行压缩整顿以打消内存碎片(此处内存碎片是死亡对象之前所占用的空间)。
- 新生代应用复制算法存在的缺点,因为应用了复制算法,每次只能应用 1/2 的空间,可应用的内存空间变成了 1/2。
- 因为存在 2. 中形容的缺点,要想方法优化,让复制算法中可应用内存空间 > 1/2。优化方法是从 eden 区 : survivor 区 = 1 : 1,变为 eden 区 : survivor 区 = 8 : 2,这样可应用内存空间就变成了 8/10。然而这样在下一次 Young GC 后,存活对象挪动到 survivor 区,咱们的可应用区域只有 2/8,太小了。
- 持续优化 3. 中形容的问题,咱们把新生代分为 eden 区 : survivor0(from) : survivor1(to) = 8 : 1 : 1,每次新生代对象在 eden 区创立,上一次 GC 存活的对象在 from 区,下次 GC 时要挪动的对象是 eden 区和 from 区中存活的对象,挪动至 to 区,而后 from 区和 to 区身份替换。这样咱们新生代可应用的内存空间就有 9/10(eden + from) 了。
上述解决方案的演进为 “JVM 新生代为什么要有两个 survivor(from, to) 区 ” 的起因。
正文完