垃圾回收机制学习总结

链接一篇讲的非常棒的文章

https://juejin.cn/post/6981588276356317214#heading-21

提出一些问题:方便后续回顾垃圾回收机制。

1、什么是垃圾回收机制?

GC 即 Garbage Collection ,程序工作过程中会产生很多 垃圾,这些垃圾是程序不用的内存或者是之前用过了,以后不会再用的内存空间,而 GC 就是负责回收垃圾的,他工作在引擎内部,这一套引擎执行操作就是 垃圾回收机制 了

2、为什么要进行垃圾回收?

JavaScript 的引用数据类型是保存在堆内存中的,然后在栈内存中保存一个对堆内存中实际对象的引用,所以,JavaScript 中对引用数据类型的操作都是操作对象的引用而不是实际的对象。可以简单理解为,栈内存中保存了一个地址。

举个例子

let a = {
	age : "555"
}

a = [1,2,3]

首先我们声明了一个变量a ,它引用了对象{age : “555”},然后把变量重新赋值了一个数组对象,该变量变成了引用一个数组,他就和{age:“555”}没有关系了。没有了引用关系就是无用的对象,多了的话内存也会受不了,所以要进行垃圾回收。

3、垃圾应该怎么回收?

就是删除这些垃圾释放内存呗

4、回收策略有哪些?

标记清除法

引用计数法

5、标记清除算法的逻辑? 优点是什么?缺点是什么?

标记清除法算法逻辑:下面画了个大致的逻辑图
在这里插入图片描述
优点: 实现比较简单,打标记就两种情况

缺点:在清除之后,剩余的对象内存位置是不变的,会导致内存空间不连续,出现碎片化,就会牵扯到内存分配问题。如下图所示

粉色代表需要清理的对象,白色代表空闲内存,蓝色代表无需清理的内存。在粉色内存清除之后,发现内存空间不是连续的,是间断的
在这里插入图片描述
所以在我们下一次分配内存空间时,要怎么样找到合适的块儿呢?

1、first-fit: 找到大于等于size的块的立刻返回(速度和效率很快)
2、Best-fit:遍历整个空闲列表,返回大于等于size的最小分块(分配速率很慢)
3、worst-fit:遍历整个空闲列表,找到最大的分块,然后切成两部分,一部分size大小,并将该部分返回(会造成更多的碎片)

所以,标记清除算法有两个很明显的缺点1、导致内存空间碎片化。2、内存分配速度慢

怎么解决这些个缺点呢?
标记整理算法:她跟标记清除算法的区别只有一点,就是标记结束后,会将内存空间往左移动,这样剩下的空内存就全在右边了。

6、引用计数算法的逻辑?优点是什么?缺点是什么?
算法逻辑:
1、当声明了一个变量并且将一个引用类型赋值给该变量的时候这个值的引用次数就为 1
2、如果同一个值又被赋给另一个变量,那么引用数加 1
3、如果该变量的值被其他的值覆盖了,则引用次数减 1
4、当这个值的引用次数变为 0 的时候,说明没有变量在使用,这个值没法被访问了,回收空间,垃圾回收器会在运行的时候清理掉引用次数为 0 的值占用的内存

例子如下

let a = new Object() 	// 此对象的引用计数为 1(a引用)
let b = a 		// 此对象的引用计数是 2(a,b引用)
a = null  		// 此对象的引用计数为 1(b引用)
b = null 	 	// 此对象的引用计数为 0(无引用)
...			// GC 回收此对象

优点:清晰很多,引用计算在引用值为0时,就会被立即回收,而标记算法需要每隔一段时间进行一次

缺点:计数器占用位置很大,且没有上限会占用很多内存。无法解决循环引用的问题(最严重的BUG)

7、可达性是什么?不可达性是什么

可达性:以某种方式可以被访问或者使用的值就是可达性,否则为不可达性

8、分代收集算法?
即新生代垃圾回收算法加老生代垃圾回收算法,下面会详细说到

9、讲一下分代式垃圾回收?为什么需要分代式?V8对CG的优化是什么?

分代式机制把一些新、小、存活时间短的对象作为新生代采用一小块内存频率较高的快速清理,而一些大、老、存活时间长的对象作为老生代,使其很少接受检查,新老生代的回收机制及频率是不同的,可以说此机制的出现很大程度提高了垃圾回收机制的效率

10、讲一下新生代垃圾回收和老生代垃圾回收?

新生代垃圾回收: 即复制算法

新生代活动空间只有1-8M

(1)、将堆内存一分为二,一个为使用区,一个为空闲区,新加入的对象都会被放入使用区。当使用区快被写满时,进行垃圾清理操作。
(2)、对使用区的活动对象做标记
(3)、将使用区的所有对象复制到空闲区并进行排序
(4)、把空闲区的非活动对象的占用空间清理掉。然后空闲区变为使用区,使用区变为空闲区。

当一个对象经过多次复制后依然存货,它会被认为是生命周期较长的对象,随后被移动到老生代中,如果一个对象复制到空闲区时,空闲空间占用超过了25%,这个对象会直接被晋升到老生代中(因为翻转占比过大会影响后续内存分配)。

老生代垃圾回收
就是标记清除算法,V8还使用了标记整理法解决标记清除算法产生的内存碎片问题。

11、增量标记与懒性清理、三色标记法(暂停与恢复),写屏障(增量中修改引用)?

**增量标记:**就是讲一次GC标记的过程。分成了很多小步,每执行完一小步就让应用逻辑执行一会儿,这样交替多次后完成一轮GC标记。

**懒性清理:**增量标记完成之后,懒性清理就开始。我们没有必要立即清理内存,可以将清理过程稍微延迟一下,先执行javascript脚本代码,逐一进行清理,直到所有非活动内容清理完,再进行增量标记

三色标记法:

(1)、执行一次完整的GC标记前,垃圾回收机制会将所有的数据置为白色。
(2)、从一组根对象开始,将这组跟对象标记为灰色并推入到标记工作表中,当回收器从标记工作表中弹出对象并访问它的引用对象时,将其自身由灰色转变成黑色,并将自身的下一个引用对象转为灰色。
(3)、一直往下走直到没有可标记的灰色的对象时,就是无可达,剩下的白色对象都是无法到达等待回收的

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值