java的新生代、老年代、Eden、Survivor的关系
新生代、老年代是根据对象的存活时长区分的,它们都属于内存分区中的“堆”,都是“堆”的一部分。一般来说(因为有些很大的对象可能一开始就创建在老年代),新建的对象都存放于新生代区,新生代区每经过一次垃圾回收而仍存活下来的对象其年龄就加1,这样,有的对象就可能历经多次新生代区垃圾回收后仍然在活着,达到阈值(默认15)后就会被移到老年代。
Eden、Survivor则是垃圾回收算法相关的,属于 复制算法,也是目前商业虚拟机使用在新生代区的垃圾回收算法。目前商业虚拟机普遍采用分代收集的方案--- 新生代区采用复制算法收集垃圾,老年代则采用 标记-清理 或 标记-整理 算法,也就是对新生代、老年代两个区域分别采取不同的垃圾收集算法。说回咱们的Eden、Survivor,在复制算法中,通常将新生代区再按8(Eden):1(Survivor):1(Survivor)的比例分成3块,使用时总是有一块Survivor是空闲的,每当垃圾回收时就将Eden和另一个Survivor中的存活对象移动到这块空闲的Survivor区,这样就完成了一次垃圾回收,Eden被挪空后就又可以接收新建的对象。之所以Eden和Survivor合计占比9的区域里的对象能存放到另一块占比仅为1的Survivor区域,是因为大多数对象都是朝生夕死,即每次垃圾回收都会大概率清除掉绝大部分的对象。如果遇到意外情况,另一块Survivor存放不下,则就需要老年代区域来担保,即把存放不下的对象转移到老年代区。这又涉及到担保策略的问题,请去其他地方搜索。
综上所述,新生代、老年代是根据对象存活时长划分的两个区域,Eden、Survivor则是复制算法在实施过程中划分出的区。新生代中的对象存活得够久,就会触发阈值进入到老年代,新生代中的对象存活得够多,空闲survivor容不下了,也可能会因为老年代的担保机制而进入到老年代。
更多推荐
所有评论(0)