【前端知识之JS】JS内存泄漏
前言
本系列主要整理前端面试中需要掌握的知识点。本节介绍JS中内存泄漏的几种情况 。
文章目录
- 前言
- 一、什么是内存泄漏
- 二、垃圾回收机制
- 1、标记清除——JS最常用的垃圾回收机制
- 2、引用计数
- 三、常见的内存泄漏情况
- 1、意外的全局变量
- 2、定时器
- 3、闭包
- 4、没有清理DOM元素
一、什么是内存泄漏
- 内存泄漏是在计算机科学中,由于疏忽或错误造成程序未能释放已经不再使用的内存,并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。
- C语言中,由于是手动管理内存,因此内存泄漏是经常出现的事情。
char * buffer;
buffer = (char*) malloc(42);// Do something with bufferfree(buffer);
- C语言中,malloc用来申请内存,使用完毕后,比较自己用free方法释放内存。这显然很不智能,所以大多数语言提供自动内存管理,减轻程序员负担,这被称为“垃圾回收机制”。
二、垃圾回收机制
- JS具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存。
- 原理:垃圾收集器会定期找出那些不再继续使用的变量,然后释放其内存;
- 通常情况下有两种实现方式:
- 标记清除;
- 引用计数
1、标记清除——JS最常用的垃圾回收机制
- 当变量进入执行环境时,就标记这个变量为“进入环境”。进入环境的变量所占用的内存就不能释放,当变量离开环境时,则将其标记为“离开环境”。
- 垃圾回收程序运行的时候,会标记内存中存储的所有变量。然后会将所有在上下文的变量,以及被在上下文中变量引用的变量的标记去掉。
- 在此之后再被加上标记的变量就是待删除的了,原因时任何在上下文中变量都访问不到它们了;
- 随后垃圾回收程序做一次内存清理,销毁带标记的所有值并收回他们的内存。
var m = 0,n = 19 // 把 m,n,add() 标记为进入环境。
add(m, n) // 把 a, b, c标记为进入环境。
console.log(n) // a,b,c标记为离开环境,等待垃圾回收。
function add(a, b) {a++var c = a + breturn c
}
2、引用计数
- 语言引擎有一张“引用表”,保存了内存里面所有的资源(通常是各种值)的引用次数。如果一个值的引用次数是0,就表示这个值不再用到了,因此可以将这块内存释放。
- 如果一个值不再需要了,引用数却不为0,垃圾回收机制无法释放这块内存,从而导致内存泄漏。
const arr = [1, 2, 3, 4]; //数组是一个值,会占用内存,变量arr是仅有的对这个值的引用,因此引用次数为1。
console.log('hello world'); //这里并没有用到arr,但还是会持续占用内存
- 如果需要这块代码被垃圾回收机制释放,那么只需要设置
arr=null
,数组的引用次数就为0了,就被垃圾回收了。
三、常见的内存泄漏情况
1、意外的全局变量
// 情况1,没有修饰符
function foo(arg) {bar = "this is a hidden global variable";
}// 情况2,this创建的全局变量
function foo() {this.variable = "potential accidental global";
}
// foo 调用自己,this 指向了全局对象(window)
foo();
2、定时器
var someResource = getData();
setInterval(function() {var node = document.getElementById('Node');if(node) {// 处理 node 和 someResourcenode.innerHTML = JSON.stringify(someResource));}
}, 1000);
如果id为Node的元素从DOM中移除,该定时器仍会存在,同时,因为回调函数中包含对someResource的引用,定时器外面的someResource也不会被释放
3、闭包
function bindEvent() {var obj = document.createElement('XXX');var unused = function () {console.log(obj, '闭包内引用obj obj不会被释放');};obj = null; // 解决方法
}
闭包维持函数内局部变量,使其得不到释放。
4、没有清理DOM元素
const refA = document.getElementById('refA');
document.body.removeChild(refA); // dom删除了
console.log(refA, 'refA'); // 但是还存在引用能console出整个div 没有被回收
refA = null;
console.log(refA, 'refA'); // 解除引用
没有清理对DOM元素的引用同样造成内存泄露,包括使用事件监听addEventListener监听的时候,在不监听的情况下使用removeEventListener取消对事件监听。
【前端知识之JS】JS内存泄漏相关推荐
- vue中解决three.js出现内存泄漏丢失上下文问题
vue中解决three.js出现内存泄漏丢失上下文问题 参考文章: (1)vue中解决three.js出现内存泄漏丢失上下文问题 (2)https://www.cnblogs.com/lichuank ...
- 排查 Node.js 服务内存泄漏,没想到竟是它?
背景 团队最近将两个项目迁移至 degg 2.0 中,两个项目均出现比较严重的内存泄漏问题,此处以本人维护的埋点服务为例进行排查.服务上线后内存增长如下图,其中红框为 degg 2.0 线上运行的时间 ...
- JS引起内存泄漏的情况
1. 意外的全局变量 全局变量的生命周期最长,直到页面关闭前,它都存活着,所以全局变量上的内存一直都不会被回收. 当全局变量使用不当,没有及时回收(手动赋值 null),或者拼写错误等将某个变量挂载到 ...
- 【JavaScript】js中内存泄漏的几种情况?
文章目录 一.是什么 二.垃圾回收机制 标记清除 引用计数 小结 三.常见内存泄露情况 参考文献 一.是什么 内存泄漏(Memory leak)是在计算机科学中,由于疏忽或错误造成程序未能释放已经不再 ...
- js中内存泄漏的几种情况
内存泄漏:由于疏忽或错误造成程序未能释放已经不再使用的内存 1)意外的全局变量 解决方法:严格模式进行检测 例:函数内部定义全局变量(直接赋值) 2)定时器 不用的时候,及时清除定时器 没油及时清除的 ...
- js中内存泄漏与内存溢出
内存泄漏: 占用的内存没有及时的释放从而失去控制,从而造成内存的浪费.内存泄漏多了就容易引发内存溢出. 常见的造成内存泄漏的原因: (1)没有清除闭包 // 函数执行完后, 函数内的局部变量没有释放, ...
- 「JavaScript灵魂之问」前端知识梳理之 JS 篇(中篇)
对象基础 对象前置知识 /* 对象基础知识 */var teacher = {name: '张三',age: 32,sex: 'male',height: 176,weight: 130,teach: ...
- js日期比较大小_node.js 内存泄漏的秘密
每日前端夜话第276篇 翻译:疯狂的技术宅 作者:Giovanny Gongora 来源:nodesource 正文共:3955 字 预计阅读时间:10分钟 一直以来,跟踪 Node.js 的内存泄漏 ...
- javascript内存泄漏调试工具mac_node.js 内存泄漏的秘密
一直以来,跟踪 Node.js 的内存泄漏是一个反复出现的话题,人们始终希望对其复杂性和原因了解更多. 并非所有的内存泄漏都显而易见.但是,一旦我们确定了其模式,就必须在内存使用率,内存中保存的对象和 ...
最新文章
- linux什么命令只显示ip,linux ip命令
- 如何检查变量是否是JavaScript中的数组? [重复]
- 2 resize 到指定大小_阿里巴巴为什么让初始化集合时必须指定大小?
- 数据结构与算法--10.利益最大值
- 二.路径规划---二维路径规划实车实现---gmapping+amcl+map_server+move_base
- java读取sh脚本_linux环境下java读取sh脚本并执行
- iframe 父级元素查找
- Split的使用(C#)
- Kafka从上手到实践 - 实践真知:搭建单机Kafka | 凌云时刻
- 【车牌识别】基于matlab车牌识别【含Matlab源码 417期】
- 浅论照明节能的系统设计
- python遥感数据有偿处理_地质男转行学遥感Python——DMSP数据预处理一
- Java Map是否有序
- 百度披露被黑原委 黑客骗得邮箱
- 【附源码】计算机毕业设计SSM食疗养生服务平台
- arcgis pro发布矢量切片服务及利用arcgis api for javascript进行调用
- Comparable的compareTo
- php上传图片到mysql并显示
- postman接口自动化测试之判断结果是否符合预期
- Linaro Android 4.4.2系统下载和使用(arndale octa board)