zoukankan      html  css  js  c++  java
  • JVM垃圾回收(三)- GC算法:基础

    GC算法:基础

    在介绍GC算法在实际场景中的实现之前,我们先定义一些必要的术语,以及GC算法的基本准则。具体的细节会因收集器的不同而稍有区别,但是基本上来说,所有的收集器会关注以下两个方面:

    1. 找出所有仍然存活的对象
    2. 清除掉其他所有非存活对象(被认为是dead,并且不会再被使用的对象)

    在所有的收集器内部,第一步实现的均是:遍历出所有存活的对象。由标记(Marking)进程完成。

    标记所有可达对象

    在JVM中,任何主流GC算法均会以找出所有存活对象为开始。这个概念的解释可以参考下图:

    首先,GC定义某些特定的对象为Garbage Collection Roots,一些典型的GC roots如:

    1. 当前执行的方法中的本地变量以及输入参数
    2. 当前活跃的线程
    3. 已载入的类中的静态区域
    4. JNI(Java Native Interface)引用

    下一步,GC遍历内存里的整个对象图(whole object graph),从GC roots开始,遍历它们引用的所有对象。任何被GC访问到的对象会被标注为存活。

    在上图中,蓝色的圆圈表示存活的对象。当Marking阶段完成时,所有存活的对象会被标注。所有其他对象(上图中的灰色圆圈)便是无法由GC roots访问到的对象,也就是说,你的应用无法再使用这些不可达的对象。这种对象被认为是垃圾,GC在清除它们时会经历以下阶段:

    1. 应用中的线程需要被停止,以便让Marking阶段正常运行。因为应用若是持续运行,则JVM里的对象可能随时在变化,这样就不足以获取到精确的信息。这个场景被称为一个安全点(safe point),它造成的结果便是一个Stop The World pause。Safe point可被不同的原因触发,但是到现目前为止,GC是引入safe point最常见的原因
    2. 这个暂停持续的时间并不取决于堆内存里对象的总数量,也不取决于堆内存的大小。它是由存活的对象个数决定的。所以,增加堆内存的大小并不会直接影响marking阶段的持续时间

    Removing Unused Objects

    不同的GC算法中,清楚unused objects的方式稍有不同。但是所有这类GC算法基本上可以分为以下三组:

    1. Sweeping
    2. Compacting
    3. Copying

    Sweeping

    Mark and Sweep 算法对于垃圾使用了最简单的方式:忽略掉这些对象。具体的说,就是在marking阶段完成后,所有没被访问到的对象所占据的空间,均被视为可用的空间。并可以被用于为新的对象分配。

    这种方式使用到一种名为free-list的结构来记录每个空闲的区域(region)以及它的大小。free-list的管理方法会增加对象分配(object allocation)的开销。并且,它会有一个缺点:可能会存在大量的空闲region,但是如果单个region的空间不足以满足一个allocation,则这个allocation也会失败,并返回OutOfMemoryError的报错。

    Compact

    Mark-Sweep-Compact算法解决了Mark and Sweep的缺点。它将所有被标注为存活的对象移动到内存区域的起始。这种方法的缺点是增加了每次GC暂停的时间,因为我们需要将所有的对象移动到一个新的地方,并且更新它们的引用。它的优点也显而易见:在这个compacting操作完成后,对于新对象的分配会非常容易。使用这种方式,空余空间的地址随时可获取,并且也不会有碎片的问题。

     

    Copy

    Mark and Copy算法与Mark and Compact非常接近,因为它们都会重新allocate所有存活的对象。比较重要的不同点是:Mark and Copy 重分配的目标空间在一个不同的内存区域。它的优点是可以与Marking阶段并行执行。缺点是它需要一个足够大的额外内存区域,以支持所有的存活对象。

    References:

    https://plumbr.io/handbook/garbage-collection-algorithms

  • 相关阅读:
    什么是接口测试?怎样做接口测试?
    python下批量执行多条py文件的方法
    Jmeter运行报错software caused connection abort:recv failed
    性能测试一般容易出现瓶颈点
    性能测试流程规范(较好文档)
    Jmeter代理录制获取登录参数_移动端设置代理
    Http请求与WebSocket请求区别(WebSocket协议简析)
    JSONObject方法提取响应数据中的值
    Jmeter学习资料、控件下载地址大全
    图解IntelliJ IDEA 13版本对Android SQLite数据库的支持
  • 原文地址:https://www.cnblogs.com/zackstang/p/10091847.html
Copyright © 2011-2022 走看看