JavaScript的垃圾回收机制与内存泄漏
常用的两种算法:
引用计数(新版浏览器已弃用,弃用原因:会出现循环引用的情况,无法进行垃圾回收,导致内存泄漏)
标记清除
引用计数法
引用计数,顾名思义一个对象是否有指向它的引用,即看栈中是否有指向要释放的该块堆内存中的地址,如果没有,则该块内存是不需要的,可以进行释放,即垃圾回收
下面引用大佬的一个简短例子来说明情况
// 创建一个对象person,他有两个指向属性age和name的引用
var person = {
age: 12,
name: 'aaaa'
};
person.name = null; // 虽然name设置为null,但因为person对象还有指向name的引用,因此name不会回收
var p = person;
person = 1; //原来的person对象被赋值为1,但因为有新引用p指向原person对象,因此它不会被回收
p = null; //原person对象已经没有引用,很快会被回收
缺点:引用计数有一个致命的问题,那就是循环引用
当两个对象相互引用,尽管他们已不再使用,但是垃圾回收器不会进行回收,最终可能会导致内存泄露。
function cycle() {
var o1 = {};//
var o2 = {};//
o1.a = o2;//
o2.a = o1; //
return "cycle reference!"
}
cycle();
cycle
函数执行完成之后,对象o1
和o2
实际上已经不再需要了,但根据引用计数的原则,他们之间的相互引用依然存在,因此这部分内存不会被回收。所以现代浏览器不再使用这个算法。
但是IE依旧使用。
var div = document.createElement("div");
div.onclick = function() {
console.log("click");
};
上面的写法很常见,但是上面的例子就是一个循环引用。
变量div有事件处理函数的引用,同时事件处理函数也有div的引用,因为div变量可在函数内被访问,所以循环引用就出现了。
标记清除(常用)
文章里写的是:标记清除算法将“不再使用的对象”定义为“无法到达的对象”。即从根部(在JS中就是全局对象)出发定时扫描内存中的对象,凡是能从根部到达的对象,保留。那些从根部出发无法触及到的对象被标记为不再使用,稍后进行回收。
我这里个人理解:不在原型链上的,不能从全局对象链找到的对象,会被认为是无法到达的对象(也可能我自己理解有误,忘读者指出),比如说下面这个例子
var a = {} // 这里的a是挂在全局对象上的 a = null // 这里a之前存放指向{}的地址变成了null // 此时{}是无法找到的,通过全局对象找到a也无法到达{},因此{}会被垃圾回收
无法触及的对象包含了没有引用的对象这个概念,但反之未必成立。
所以上面的例子就可以正确被垃圾回收处理了。
所以现在对于主流浏览器来说,只需要切断需要回收的对象与根部的联系,就能进行垃圾回收
下面还是引用大佬的例子
最常见的内存泄露一般都与DOM元素绑定有关:
email.message = document.createElement(“div”);
displayList.appendChild(email.message);
// 稍后从displayList中清除DOM元素
displayList.removeAllChildren();
上面代码中,div
元素已经从DOM树中清除,但是该div
元素还绑定在email对象中,所以如果email对象存在,那么该div
元素就会一直保存在内存中
参考文章:(https://www.muyiy.cn/blog/1/1.4.html#垃圾回收算法)
最新文章
- python中configparser模块
- unity4.6学习Ugui中文文档-------参考-UGUI Rect Transform
- boundingRectWithSize
- Python 列表
- html与js的取值,赋值
- 1069 Nim游戏
- CSS布局基础
- BZOJ 1059 [ZJOI2007]矩阵游戏
- HDU 4810 这道题 是属于什么类型?
- 电子设计省赛--DMA与ADC
- 一段代码让你秒懂java方法究竟是传值还是传地址
- Asp.Net Core 中无法使用 ConfigurationManager.AppSettings
- zabbix agent(Active)模式 /克隆修改模板
- django中forms和modelform组件的区别
- java爬虫代理
- Linux 端口转发一则
- CSS--居中方式总结
- linux下使用screen和ping命令对网络质量进行监控
- MSP MCU I2C入门指南
- dingyou-dingtalk-mobile在安卓系统上无法显示问题
热门文章
- Java编程思想:泛型接口
- request 中url拼接排序参数与签名算法
- 和朱晔一起复习Java并发(三):锁(含锁性能测试)
- python菜鸟基础知识(一)
- https://www.cnblogs.com/M-LittleBird/p/5902850.html
- android异常 More than one file was found with OS independent path 'META-INF/XXX'
- [leetcode]914. X of a Kind in a Deck of Cards (easy)
- Unity AR Foundation 和 CoreML: 实现手部的检测和追踪
- 金蝶K3 V12.2版本,中途启用双计量单位出现错误
- TestNg中的断言你真的了解吗