GC —— 垃圾回收机制认识与算法详解

2020-12-13  本文已影响0人  顽皮的雪狐七七

目录

GC相关概念

常见GC算法

引用计数算法

核心思想

设置引用数,判断当前引用数是否为0来决定是不是垃圾对象,如果是0GC就进行工作,进行回收。

实现原理

实例

const user1 = { age: 11 }
const user2 = { age: 12 }
const user3 = { age: 13 }
const nameList = [user1.age, user2.age, user3.age]

function fn() {
  const num1 = 1
  const num2 = 2
  num3 = 3
}

fn()

当函数调用过后,num1num2在外部不能使用,引用数为0,会被回收 ;
num3是挂载在window上的,所以不会被回收 ;
上面的user1user2user3nameList引用,所以引用数不为0不会被回收 ;

优缺点

引用计数算法 内容
优点 1. 发现垃圾时立即回收
2. 最大限度减少程序暂停,让空间不会有被占满的时候
缺点 1. 无法回收循环引用的对象
2. 资源消耗开销大(对所有对象进行数值的监控和修改,本身就会占用时间和资源)

下面举一栗子说明上面缺点中无法回收循环应用对象的情况:


function fn() {
  const obj1 = {}
  const obj2 = {}
  obj1.name = obj2
  obj2.name = obj1
  return 'hello world'
}

fn()
// obj1和obj2,因为互相有引用,所以计数器并不为0,fn调用之后依旧无法回收这两个对象

标记清除算法

相比原理实现更加简单,还能解决相应问题,V8当中会大量使用到。

核心思想

标记清除 两个阶段完成

实现原理

图示

image

优缺点

标记清除算法 内容
优点 相对于引用计数算法来说解决对象循环引用的问题,局部作用域里面的内容无法被标记,所以即使有引用还是会被清除掉
缺点 1. 空间链表地址不连续(空间碎片化),不能进行空间最大化使用
2. 不会立即回收垃圾对象,清除的时候程序是停止工作的。

下面是空间链表地址不连续的图示,可以更好的帮我们理解:

image

左边释放了2个字的空间,后边释放了1个字的空间,虽然看起来是释放了3个字的空间,但是地址是不连续的。如果要申请一个1.5字的空间,使用左边空间浪费了0.5,时候右边又不够,会造成无法最大化使用。

标记整理算法

这个算法和标记清除算法配合在V8中也是广泛应用。

核心思想

标记清除 中间,添加了内存空间的 整理

实现原理

图示

开始会有很多活动对象和非活动对象,还有一些空闲空间,回收前先开始整理


image

整理之后要将非活动对象进行清除

image

最后就留出了整个的空闲空间

image

优缺点

标记整理算法 内容
优点 相较标记清除算法减少了碎片化空间
缺点 不会立即回收垃圾对象,清除的时候程序是停止工作的。
上一篇下一篇

猜你喜欢

热点阅读