1. 什么是垃圾回收机制
javaScript 垃圾回收机制简单来说就是,找出不再使用的变量,然后释放掉其所占的内存,但这个过程不是实时的,因为开销比较大,所以垃圾回收机制会按照固定的时间间隔周期性的执行。
2. 垃圾回收主要回收哪种变量(变量的生命周期)
1. 全局变量
定义在所有函数外的变量,会在 window 对象关闭后释放。
2. 局部变量
在某个函数中定义的变量,局部变量只在函数执行的过程中存在,而这个过程中会为局部变量在堆或者栈上分配相应的空间,以存储它们的值,然后再在函数中使用这个变量,直至函数结束,一旦函数结束,局部变量就没有存在的必要了,可以释放它们占的内存。
垃圾回收机制要知道那个变量有用,那个变量没用
3. 标记清除
当变量进入执行环境的时候,比如函数中声明一个变量,垃圾回收器将其标记为 “进入环境”, 当变量离开环境的时候(函数执行结束)将其标志为“离开环境”,原则上将不能够释放进入环境的变量所占的内存,因为它们随时可能会被调用到。 垃圾回收器会在运行时给存储在内存中的变量都加上标记,然后去掉环境中的变量以及被环境中变量所引用的变量(变量),在这些完成之后仍存在标记的就是要删除的变量了,因为环境中的变量已经无法访问到这些变量了,然后垃圾回收器就会释放这些带有标记的变量所占的空间。
4. 引用计数
引用计数的策略是跟踪记录,每个值被使用的次数,当声明了一个变量并将一个引用类型肤质给该变量的时候,这个值的引用次数就增加 1,如果该变量的值变成了另外一个,则这个值的引用就减 1. 当这个值的引用次数为0的时候,说明没有变量在使用。这个值就没办法访问了,因此可以将其所占的空间回收,这样垃圾回收器会在运行的时候清除掉引用次数为0的值所占的空间。 缺点: 没办法循环引用
例1:
let a = new Object() // a 的次数为 1
let b = new Object() // b 的次数为 1
let c = a // a 的次数为 2
let c = b // a 的次数为 1 b 的次数为 2
// 当循环调用时
d.prop = f // f 的次数为 2 默认次数为 1
f.prop = d // d 的次数为 2 默认次数为 1`
例2: obj 引用了 document.getElementById('element'), 而 document.getElementById('elemnt')的 onclick 方法会引用外部环境的变量,自然也包括 obj
window.onload = function outerFunction() {
var obj = document.getElementById('element');
obj.onclick = function innerFunction() {};
解决办法
window.onload = function outerFunction() {
var obj = document.getElementById('element');
obj.onclick = function innerFunction() {};
obj = null
5. 什么时候触发垃圾回收机制
-
垃圾回收器存分配量低于程序占用内存占有的15%, 说明大部分内存不可被回收,设的垃圾回收触发条件过于敏感,这个时候把临界条件翻倍。
-
如果回收的内存高于 85%, 说明大部分内存早就该清理了,这个时候把触发条件置回。