美文网首页
读书笔记-GC基础垃圾收集算法整理

读书笔记-GC基础垃圾收集算法整理

作者: 上学威龙7 | 来源:发表于2019-12-31 17:59 被阅读0次

    GC基础垃圾收集算法整理

    简单概括如下4种算法:

    1. 标记-清除算法
    2. 复制算法
    3. 标记-整理算法
    4. 分代收集算法

    对象死亡判断

    在运行算法之前,需要判断对象的死亡,有如下2种方式来进行判断:

    1. 引用计数器算法
    2. 可达性分析算法

    引用计数器算法

    定义:对象中添加一个引用计数器,当有一个地方引用它时,就+1,引用失效时,计数器值就-1。现在的java已经弃用此方法。早期还是比较适用,再如Redis 1.0也是采用此方式。存在一个著名的相互引用的问题,故后续不再火了

    可达性分析算法

    设置一个GC Roots对象作为七点,从这些节点开始向下搜索,走过的链路叫做引用链。当一个对象到GC Roots没有任何引用链相连时,则此对象是可回收的。是目前jvm常用判断对象是否死亡的方法。

    垃圾收集算法

    如下为各种算法介绍

    标记-清除算法

    Mark-Sweep 标记-清除算法,分为2个阶段
    第一阶段,标记处所有需要回收的对象。
    第二阶段,清除所有标记过的对象。

    image
    主要存在2点不足:
    • 效率问题,标记和清除两个过程效率都不高
    • 空间问题,如图可见,结束之后存在大量不连续的内存碎片,此时需要分配一个较大的对象时,会触发再一次的垃圾收集动作。

    此算法并不是完全的不使用了,而是后面的垃圾收集器中对其进行改造再使用。垃圾收集器介绍,会在下一节介绍。

    复制算法

    copy 标记-复制算法,可将内存按容量划分为大小相等的两块,每次只使用其中一块。当这一块用完了,把还存活的对象复制到另一块上面,再把已使用过的内存空间一次清理掉。每次对整个半区进行内存回收。

    image

    1:1的比例在实际使用中并不适用,在虚拟机中,一般采用8:1:1的比例来分配Eden和Survivor,符合大多数对象朝生夕死的特性。个人的理解是,8:1是用来适用朝生夕死的特性,而分成2块Survivor,是用来作为对象进入老年代的依据。也可叫做fromto

    解决了如下问题
    1、内存碎片问题,主要解决了这个
    2、按顺序分配内存,高效。

    同时也有一些缺点
    1、当对象大量存活时,频繁复制,效率降低
    2、内存空间减少了一半,需要有额外的空间进行分配担保(故其实在老年代中一般是不能采用此方法的)

    标记-整理算法

    Mark-Compact算法,分为如下2步
    1、标记需要清除的对象
    2、把所有存活的对象向一端移动,直接清理掉边界以外的对象

    image

    分代收集算法

    划分为新生代和老年代,每个年代可以选择自己适合的收集算法。

    标记过程

    上数算法中,都会去标记可回收或不可回收对象,标记的过程也是对对象进行可达性分析的过程。这项工作必须在一个能确保一致性的快照中进行,因此会出现GC停顿,称之为"stop the world"。

    在jvm中会借助,安全点和安全区来对线程进行停顿。安全点是指,当发生GC时,各个线程会主动去轮询这个标志,发现中断标志为真时就自己中断挂起。但是对于不执行的线程无法运行到安全点,比如线程处于sleep或者blocked状态,这时候线程无法响应JVM的中断请求,就需要安全区来解决。当线程进入安全区时,无须关注中断标志,但是当线程离开安全区时,需要检查系统是否已经完成了根节点枚举(或者整个GC过程)。

    总结

    介绍了几种简单的垃圾收集算法,从中发现,每个算法都有自己的优缺点,但是绕不开的是"stop the world"。后面来分析,针对GC的停顿,不同的垃圾收集器是怎么处理的。

    相关文章

      网友评论

          本文标题:读书笔记-GC基础垃圾收集算法整理

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