zoukankan      html  css  js  c++  java
  • 《垃圾回收的算法与实现》——GC标记-清除算法

    基本算法

    • 标记-清除算法由 标记阶段清除阶段 构成。
    • 标记即将所有活动的对象打上标记。
    • 清除即将那些没有标记的对象进行回收。

    标记与清除

    • 遍历GC root引用,递归标记(设置对象头中的标志位)对象。
    • 标记时如果标志位表示已经标记过则可以跳过。
    • 遍历对象有深度优先与广度优先两种算法,其搜索的步骤数一致,而深度优先的内存使用量更小,因此一般使用深度优先。
    • 清除阶段将再次遍历堆,未标记的对象加入到空闲链表中,标记的对象则去除标记。

    分配与合并

    • 分配指mutator(Application)申请分块时获取内存块的过程。
    • 分配即通过搜索空闲链表,找到一个大小合适的块。分配测量有如下:
      • First-fit,找到第一个大于要求大小的块即返回。
      • Best-fit,找到比要求大小大的最小块。
      • Worst-fit,找出最大的块将其分割成要求大小块和剩余的,一般不使用(容易产生碎片)
    • 对于内存中连续的垃圾可以对其进行合并,减少碎片。

    优缺点

    优点

    1. 算法实现简单。
    2. 与保守式GC算法兼容(对象不能被移动)。

    缺点

    1. 碎片化。
    2. 分配速度慢,每次分配需要遍历空闲链表。
    3. 与写时复制(copy-on-write)冲突,因为做GC时需要将对象头进行标记,这将导致大量的数据发生复制。
    4. STW(Stop-The-World)长,两个阶段均要遍历整个堆。

    改进

    多个空闲链表

    针对分配速度慢

    • 根据块的大小建立不同的空闲链表,相同大小的块链接到相同链表中。
    • 由于对于大块的申请比较少,因此主要针对小块建立链表,对于大块的可以都在同一个链表中,如大于2-100的分别建立各自大小的链表而大于100的都写入一个大块链表。

    BiBOP

    针对碎片化

    • 原理:将大小相近的对象整理成固定大小的块进行管理。
    • 把堆分割成固定大小的块,让每个块只能配置同样大小的对象。
    • 但是并不能很好的消除碎片化,如果对堆的分隔没控制好反而可能导致堆的利用率。

    位图标记

    针对写时复制

    • 由于GC过程需要修改对象中属性导致写时复制不兼容,因此指收集各个对象的标志位并表格化。
    • 将堆中的对象与位图对应上,而后通过位图的标志代表堆中对象的标志。
    • 优点:
      • 兼容写时复制
      • 清除阶段可以快速的去除标记。

    延迟清除法

    针对STW过长

    • 延迟清除法(Lazy-Sweep)是缩减清除操作而导致的mutator STW的方法。
    • 标记结束后不做清除操作而是在分配操作中进行。
    • 在分配时,从上次遍历结束的地方开始使用First-fit查找块,如果找不到返回NULL,此时进行标记阶段而后再次进行First-fit查找。还找不到则分配失败。
  • 相关阅读:
    Maven关于web.xml中Servlet和Servlet映射的问题
    intellij idea的Maven项目运行报程序包找不到的错误
    修改Maven项目默认JDK版本
    刷题15. 3Sum
    刷题11. Container With Most Water
    刷题10. Regular Expression Matching
    刷题5. Longest Palindromic Substring
    刷题4. Median of Two Sorted Arrays
    刷题3. Longest Substring Without Repeating Characters
    刷题2. Add Two Numbers
  • 原文地址:https://www.cnblogs.com/suolu/p/6649211.html
Copyright © 2011-2022 走看看