zoukankan      html  css  js  c++  java
  • GC垃圾回收常用算法

    引用计数算法

    假设有一个对象A,任何一个对象对A的引用,那么对象A的引用计数器+1,当引用消失时,对象A的引用计数器就-1,如果对象A的计数器的值为0,就说明对象A没有引用了,可以被回收。

    优点:

    • 实时性较高,无需等到内存不够的时候,才开始回收,运行时根据对象的计数器是否为0,就可以直接回收。
    • 在垃圾回收过程中,应用无需挂起。如果申请内存时,内存不足,则立刻报outofmember 错误。
    • 区域性,更新对象的计数器时,只是影响到该对象,不会扫描全部对象。

    缺点:

    • 每次对象被引用时,都需要去更新计数器,有一点时间开销。
    • 浪费CPU资源,即使内存够用,仍然在运行时进行计数器的统计。
    • 无法解决循环引用问题。(最大的缺点)

    复制算法(适合新生代)

    当Eden空间将要满的时候第一次触发YGC,将还有引用的对象复制到from区同时每个对象的年龄将会+1,等到了默认值15岁的时候就会被移入到old区,此时to区还是空的,同时清空Eden区,接下来再进行YGC的时候会将Eden区和from区还存活着的对象移入到to区,同时清空Eden区和from区,然后将form区和to进行交互,谁是空的谁变为to区。如果内存中的垃圾对象较多,需要复制的对象就较少,这种情况下适合使用该方式并且效率比较高,反之,则不适合。

    ​ 据统计,新生代的对象朝生夕死,90%以上的对象都无法活过eden区。

    优点:

    • 在垃圾对象多的情况下,效率较高
    • 清理后,内存无碎片

    缺点:

    • 在垃圾对象少的情况下,不适用,如:老年代内存
    • 分配的2块幸存内存空间,在同一个时刻,只能使用一半,内存使用率较低

    -XX:PretenureSizeThreshold (默认值为0)的意思是超过这个值的时候,对象直接在old区分配内存

    -XX:MaxTenuringThreshold (默认值为15) 年龄阈值 ,每个对象的前面都会有4个bit位的大小来存储他的年龄,最大为1111转为十进制就为15

    标记清除算法(适合老年代)

    标记-清除算法分为两个阶段,标记(mark)清除(sweep)

    在标记阶段,GC从根对象开始进行遍历,对从根对象可以访问到的对象都打上一个标识,一般是在对象的header中,将其记录为可达对象。

    而在清除阶段,GC对堆内存(heap memory)从头到尾进行线性的遍历,如果发现某个对象没有标记为可达对象-通过读取对象的header信息,则就将其回收;如果发现某个对象有标记为可达对象,那么就清除标记位(为下一次标记做准备)。

    在这里插入图片描述

    优点:

    • 解决了引用计数法中无法解决的循环引用问题

    缺点:

    • 效率较低,标记和清除两个动作都需要遍历所有的对象,并且在GC时,需要停止应用程序,对于交互性要求比较高的应用而言这个体验是非常差的。
    • 通过标记清除算法清理出来的内存,碎片化较为严重,因为被回收的对象可能存在于内存的各个角落,所以清理出来的内存是不连贯的。

    标记整理算法(适合老年代)

    标记压缩算法是在标记清除算法的基础之上,做了优化改进的算法。和标记清除算法一样,也是从根节点开始,对对象的引用进行标记,在清理阶段,并不是简单的清理未标记的对象,而是将存活的对象压缩到内存的一端,然后清理边界以外的垃圾,并且清除存活对象的标记位(为下一次标记做准备),从而解决了碎片化的问题。

    在这里插入图片描述

    分代算法

    因为

    新生代的垃圾较多,对象存活率较低。

    老年代对象存活率较高,垃圾较少。

    所以

    新生代适合 复制算法,因为存活的对象低,复制速度快。

    老年代适合 标记清除算法+标记整理算法混合使用,当内存碎片过多时使用一次标记整理算法。

    总结

    内存效率(时间复杂度):复制算法 > 标记清除算法 > 标记整理算法

    内存整理:复制算法 = 标记整理算法 > 标记清除算法

    内存利用率:标记整理算法 = 标记清除算法 > 复制算法

  • 相关阅读:
    BestCoder17 1001.Chessboard(hdu 5100) 解题报告
    codeforces 485A.Factory 解题报告
    codeforces 485B Valuable Resources 解题报告
    BestCoder16 1002.Revenge of LIS II(hdu 5087) 解题报告
    codeforces 374A Inna and Pink Pony 解题报告
    codeforces 483B Friends and Presents 解题报告
    BestCoder15 1002.Instruction(hdu 5083) 解题报告
    codeforces 483C.Diverse Permutation 解题报告
    codeforces 483A. Counterexample 解题报告
    NSArray中地内存管理 理解
  • 原文地址:https://www.cnblogs.com/turbo30/p/13688270.html
Copyright © 2011-2022 走看看