垃圾回收机制(Garbage Collection)简称GC
js中内存的分配和回收都是自动完成的,内存在不使用的时候会被垃圾回收器自动回收
内存的生命周期
js环境中分配的内存,一般有如下的生命周期:
1、内存分配:当我们声明变量、函数、对象的时候,系统会自动为它们分配内存
2、内存使用:即读写内存,也就是使用变量、函数等
3、内存回收:使用完毕,由垃圾回收器自动回收不再使用的内存
<script>
const age=18; //为变量分配内存
const obj={
sex:'男'
} //为对象分配内存
//为函数分配内存
function fn(){
const arr=[1,2,3];
console.log(arr)
}
</script>
说明:
全局变量一般不会回收(关闭页面回收)
一般情况下局部变量的值,不用了,会被自动回收
内存泄露:程序中分配的内存由于某种原因程序未释放或无法释放叫做内存泄漏
垃圾回收机制-算法说明
堆栈空间分配区别:
1、栈(操作系统):由操作系统自动分配释放函数的参数值、局部变量等,基本数据类型放在栈里面。
2、堆(操作系统):一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。复杂数据类型放到堆里面。
下面介绍两种常见浏览器垃圾回收算法:引用计数算法和标记清除法
引用计数法
IE采用引用计数算法,定义"内存不在使用",就是看一个对象是否有指向它的引用,没有引用就回收对象
1、跟踪记录被引用次数
2、如果引用了依次,那么就记录次数1,多次引用会累加++
3、如果减少一个引用就减1 --
4、如果引用次数是0,则释放内存
缺点
但它存在一个致命的问题:嵌套引用(循环引用)
如果两个对象互相引用,尽管他们已不再使用,垃圾回收器也不会进行回收,导致内存泄漏。
<script>
function fn(){
let obj=
}
let obj2={
}
obj.a=obj2
obj2.a=obj
return '引用计数无法回收'
}
fn()
//因为他们的引用次数永远不会是0.这样的相互引用如果说很大量的存在就会导致大量的内存泄漏
</script>
标记清除法
现代的浏览器已经不再使用引用计数算法了。
现代浏览器通用大多是基于标记清除法的某些改进算法,总体思想是一致的。
核心:
1、标记清除算法"不再使用的对象",定义为"无法达到的对象"。
2、就是从根部(在js中就是全局对象)出发定时扫描内存中的对象。凡是能从根部到达的对象,都是还需要使用的。
3、哪些无法由根部出发触及到的对象标记为不再使用,稍后进行回收。