美文网首页
垃圾收集算法

垃圾收集算法

作者: 陈桐Caliburn | 来源:发表于2020-07-03 07:13 被阅读0次

    垃圾收集算法

    1、标记-清除算法(mark-sweep)

    首先标记出所有需要回收的对象,在标记完成后统一进行回收所有被标记对象
    存在问题:
    1、效率问题,标记和清除两个过程效率不高
    2、空间问题,标记清除后产生大量不连续内存碎片,空间碎片太多可能导致程序后续分配大对象时,提前触发gc

    2、标记-整理算法(mark-compat)

    标记出所有需要回收的对象,标记完成后,让所有存活对象都向一端移动,直接清理掉端边界以外的内存。
    标记-整理算法在标记-清除算法基础上,又进行对象移动,因此成本更高,但解决内存碎片问题。该垃圾回收算法适用于对象存活率搞得场景(老年代)

    3、复制算法

    复制算法将可用内存容量划分为大小相等两块,每次只使用其中一块,当一块内存用完,就将存货的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。算法适用于对象存活率低的场景,比如新生代。
    IBM公司研究,新生代中的对象98%朝生夕死,分配比例8:1
    Eden:Survivor0:Survivor1= 8:1:1。意外情况需要依赖其他内存(老年代)进行分配担保

    4、分代收集算法

    根据对象生存周期不同将内存进行划分。
    新生代对象存活率低,采用复制算法
    老年代存活率高,就采用标记-清除算法或标记-整理算法

    • 1、新生代
      1.所有新生成的对象首先都是放在新生代的。新生代的目标就是尽可能快速的收 集掉那些生命周期短的对象。
      2.新生代内存按照 8:1:1 的比例分为一个 eden 区和两个 survivor(survivor0,survivor1)区。大部分对象在 Eden 区中生成。回收时先将 eden 区存活对象复制到一个 survivor0 区,然后清空 eden 区,当这个 survivor0 区也 存放满了时,则将 eden 区和 survivor0 区存活对象复制到另一个 survivor1 区, 然后清空 eden 和这个 survivor0 区,此时 survivor0 区是空的,然后将 survivor0 区和 survivor1 区交换,即保持 survivor1 区为空, 如此往复。
      3.当 survivor1 区不足以存放 eden 和 survivor0 的存活对象时,就将存活对象直 接存放到老年代。若是老年代也满了就会触发一次 Full GC,也就是新生代、老
      年代都进行回收。
      4.新生代发生的 GC 也叫做 Minor GC,MinorGC 发生频率比较高(不一定等 Eden 区满了才触发)。

    • 2、老年代
      1.在老年代中经历了 N 次垃圾回收后仍然存活的对象,就会被放到老年代中。因 此,可以认为老年代中存放的都是一些生命周期较长的对象。
      2.内存比新生代也大很多(大概比例是 1:2),当老年代内存满时触发 Major GC, 即 Full GC。Full GC 发生频率比较低,老年代对象存活时间比较长。

    • 3、持久代
      永久代主要存放静态文件,如java类,方法,永久代对垃圾回收没有显著影响

    • 4、垃圾回收有两种类型,Minor GC 和 Full GC。

      Minor GC:对新生代进行回收,不会影响到年老代。因为新生代的 Java 对象大多死亡频繁,所以 Minor GC 非常频繁,一般在这里使用速度快、效率高的算法,使垃圾回收能尽快完成。

      Full GC:也叫 Major GC,对整个堆进行回收,包括新生代和老年代。由于Full GC需要对整个堆进行回收,所以比Minor GC要慢,因此应该尽可能减少Full GC的次数,导致Full GC的原因包括:老年代被写满、永久代(Perm)被写满和System.gc()被显式调用等。

    5、垃圾收集器

    垃圾收集器

    相关文章

      网友评论

          本文标题:垃圾收集算法

          本文链接:https://www.haomeiwen.com/subject/thedqktx.html