• 深入理解新生代为什么要分两个Survivor区?


    为什么堆要分新生代和老年代呢?

    假设一下,如果不分新老代,内存就一整块,垃圾收集器每次都要把那些长期存在的对象,和生命周期很短的对象放在一起回收,一般长生命周期的对象可能跟应用生命周期一致,你基本回收不掉的,比如Spring 框架里面的Bean管理相关的对象(ApplicationContext),整个应用运行期间都存在,这种一般经过几次回收最后都放在老年代,但是如果不区分新老代,每次都一起回收,性能消耗很大。

    区分新老代之后,老年代放长期存活的对象,新生代就放生命周期短的对象,老年代对象很稳定,新生代回收不影响老年代,回收效率能大大提高。

    新生代为什么不用垃圾清除或者垃圾整理算法

    若是在新生代使用垃圾清除或者垃圾整理算法,显然不需要对新生代进行分区。

    若是采用标记清除算法:会在新生代产生内存碎片,但是新生代是Java 新对象的出生地,内存碎片化显然是我们不想看到的;

    若是采用标记整理算法:虽然标记整理可以解决内存碎片化问题,但是考虑到新生代98%的对象都是“朝生夕死”的,对象被回收掉后会产生很多内存碎片,我们移动存活对象的时候需要耗费大量的时间,远不如直接把这2%对象放到另一个地方采用复制算法更加高效。

    为什么新生代还要分Eden、From、To区域呢?

    前面的分析我们已经得出结论:新生代采用复制算法更加高效。

    如果没有Survivor区(From + To),Minor GC(新生代回收)过程中,存活的对象直接被送到老年代,这样的话老年代很快被填满,触发Major GC(因为Major GC一般伴随着Minor GC,也可以看做触发了Full GC),Full GC频繁会影响程序的执行和响应速度。

    为什么要设置两个Survivor区呢?From 和 To

    前面的分析我们已经得出结论:新生代采用复制算法更加高效,且需要对新生代进行分区。

    主要还是效率问题,假设将新生代分为Eden和Survivor两个区域,显然对Eden区采用复制算法,对Survivor区采用标记整理算法,这样又回到在新生代使用复制算法效率比标记整理效率高的分析。所以需要通过将Survivor区分为From 和 To区解决。

  • 相关阅读:
    目录或文件被损坏且无法读取怎么办
    mvn前端node版本工具操作手册
    经典算法思想1——动态规划( Dynamic Programming)
    二叉树的遍历
    2.1最长递增子序列动态规划解法
    二叉树遍历分析(后缀算法的灵魂)
    记一次hive提交spark任务报错
    Ue4 CharacterMovementComponent 角色移动组件
    Ue4 TArray的属性同步
    Python 特殊语法 filter、map、reduce、lambda、yield
  • 原文地址:https://www.cnblogs.com/CoderHao/p/15126937.html
Copyright © 2020-2023  润新知