文章参考:小火柴的前端小站
文章参考地址:
js垃圾回收机制原理给你聊的明明白白 - 腾讯云开发者社区-腾讯云 (tencent.com)
(2条消息) Javascript基础:垃圾回收机制_innagine的博客-CSDN博客
一、内存的生命周期:
(1)分配内存
(2)使用所分配的内存
(3)释放内存
Javascirpt具有垃圾回收机制,会按照固定时间间隔周期性的执行操作,用来释放那些不再使用的变量所占用的内存。
二、常见的垃圾回收方式:
(1)标记清除(mark and sweep)
当变量进入执行环境(声明变量)的时候,被标记为“进入环境”,当该变量离开环境的时候,将其再度标记为“离开环境”,随之进行删除。
//例
function sayHi(){
let msg = 'Hello';//标记为“进入环境”
return msg;//标记为“离开环境”
}
console.log(sayHi());
//输出 Hello 里面被标记过的变量 又被标记为离开环境,最后回收了
//过程
/*
1.垃圾回收器在运行的时候会给存储在内存中的所有变量都加上标记(mark)
2.去掉环境中的变量以及被环境中的变量引用的变量的标记(sweep)
3.之后再被加上标记的变量 ==> 准备删除的变量(不能访问或者是不再使用这些变量)
4.完成内存清理工作,销毁加上标记的变量,回收内存空间
*/
(2)引用计数
跟踪记录每个值被使用的次数。
声明了一个变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加1;
同一个值又被赋值给另一个变量,这个引用类型值的引用次数加1;
如果该变量的值赋值为另外一个值,则这个引用类型值的引用次数减1;
若引用次数为 0,那么在垃圾回收期下次运行时,会释放所有引用次数为 0 的值所占用的内存。
let hobby = ["basketball","football","sing"];
function newHobby(){
let new_hobby = ["study","dance","etc"];//被引用次数加1
hobby = new_hobby;//被引用次数加1
}
newHobby();
console.log(hobby);
//分析
/*
函数内部声明了一个局部变量 new_Hobby, 用一个引用类型的数组赋值给 new_Hobby
同时又将变量 new_Hobby 赋值给了全局变量 hobby
思考:new_Hobby是否会被回收?
局部变量 new_Hobby 被全局变量 hobby 所引用
*/
注意:引用计数无法处理循环引用
var problem = function(){
var obj1 = {};
var obj2 = {};
obj1.foo = obj2;
obj2.Bar = obj1;
//简单理解就是两个对象被创建后,相互引用,引用次数永远不会变为 0 ,造成内存泄露
}