《对Java的分析总结》-Java中的垃圾回收机制中的标记-清除算法 (五)

标记-清除算法 


标记-清除算法(mark-sweep


1 标记-清除算法 回收过程描述

类别描述
mutator设置
collector收集
mutator rootsmutator根对象


1 在应用程序中 mutator是指除了垃圾收集器之外的部分,比如说我们应用程序本身。mutator的职责一般是NEW(分配内存),READ(从内存中读取内容),WRITE(将内容写入内存)

2 collector指的就是垃圾收集器 collector则就是回收不再使用的内存来供mutator进行NEW操作的使用

3 mutator根对象一般指的是分配在堆内存之外,可以直接被mutator直接访问到的对象,一般是指静态/全局变量以及Thread-Local变量(在Java中,存储在java.lang.ThreadLocal中的变量和分配在栈上的变量 - 方法内部的临时变量等都属于此类).



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

在标记阶段,collector(垃圾收集器)从mutator根对象开始进行遍历,对从mutator根对象可以访问到的对象都打上一个标识,一般是在对象的header中,将其记录为可达对象

在清除阶段,collector(垃圾收集器)对堆内存(heap memory)从头到尾进行线性的遍历,如果发现某个对象没有标记为可达对象-通过读取对象的header信息,则就将其回收。

collector(垃圾收集器)在进行标记和清除阶段时会将整个应用程序暂停(mutator),等待标记清除结束后才会恢复应用程序的运行,这也是Stop-The-World这个单词的来历


2 标记-清除算法 从C语言的角度来看

New():
    //allocate() C语言中的内存动态分配 
    //分配新的内存到ref指针
    ref <- allocate()  
    //如果分配的内存为 null 
    //也就是内存不足,则触发垃圾收集
    if ref == null
       collect()  
       //垃圾收集后 再分配新的内存
       //仍然内存不足,
       //则抛出Out of Memory错误
       ref <- allocate()
       if ref == null
          throw "Out of Memory"   
          return ref

atomic collect():
    //mark标记
    markFromRoots()
    sweep(HeapStart,HeapEnd)
markFromRoots():
    worklist <- empty
    for each fld in Roots  //遍历所有mutator根对象
        ref <- *fld
        if ref != null && isNotMarked(ref)  //如果它是可达的而且没有被标记的,直接标记该对象并将其加到worklist中
           setMarked(ref)
           add(worklist,ref)
           mark()
mark():
    while not isEmpty(worklist)
          ref <- remove(worklist)  //将worklist的最后一个元素弹出,赋值给ref
          for each fld in Pointers(ref)  //遍历ref对象的所有指针域,如果其指针域(child)是可达的,直接标记其为可达对象并且将其加入worklist中
          //通过这样的方式来实现深度遍历,直到将该对象下面所有可以访问到的对象都标记为可达对象。
                child <- *fld
                if child != null && isNotMarked(child)
                   setMarked(child)
                   add(worklist,child)

mark标记完成后,sweep清除阶段
就是从堆内存起始位置开始,线性遍历所有对象直到堆内存末尾,如果该对象是可达对象的(在mark阶段被标记过的),那就直接去除标记位(为下一次的mark做准备),如果该对象是不可达的,直接释放内存。

sweep(start,end):
    scan <- start
   while scan < end
       if isMarked(scan)
          setUnMarked(scan)
      else
          free(scan)
      scan <- nextObject(scan)

早起的年轻人 CSDN认证博客专家 移动开发 项目管理 Java
只要用心去做,每一件事情还是有可能成功的,当然成功是没有界限的,只不过是达到自己心里的那个目标,公众号:我的大前端生涯,一个爱喝茶的程序员,通常会搞搞SpringBoot 、Herbinate、Mybatiys、Android、iOS、Flutter、Vue、小程序等.
©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页