zoukankan      html  css  js  c++  java
  • 深入理解新生代为什么要分两个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区解决。

  • 相关阅读:
    php代码中注释的含义
    MySql-count(*)与count(id)与count(字段)之间的执行结果和性能分析
    mysql通配符进行模糊查询
    我的娃,我的宝贝
    Yii 2.0 query模式语法
    Yii 2.0版本调试输出SQL语句
    mysql高效率随机获取n条数据写法
    mysql语句中判断是否包含某字符串的方法
    应该让老婆多休息
    win10常用快捷键总结
  • 原文地址:https://www.cnblogs.com/CoderHao/p/15126937.html
Copyright © 2011-2022 走看看