前言

本系列主要整理前端面试中需要掌握的知识点。本节介绍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内存泄漏相关推荐

  1. vue中解决three.js出现内存泄漏丢失上下文问题

    vue中解决three.js出现内存泄漏丢失上下文问题 参考文章: (1)vue中解决three.js出现内存泄漏丢失上下文问题 (2)https://www.cnblogs.com/lichuank ...

  2. 排查 Node.js 服务内存泄漏,没想到竟是它?

    背景 团队最近将两个项目迁移至 degg 2.0 中,两个项目均出现比较严重的内存泄漏问题,此处以本人维护的埋点服务为例进行排查.服务上线后内存增长如下图,其中红框为 degg 2.0 线上运行的时间 ...

  3. JS引起内存泄漏的情况

    1. 意外的全局变量 全局变量的生命周期最长,直到页面关闭前,它都存活着,所以全局变量上的内存一直都不会被回收. 当全局变量使用不当,没有及时回收(手动赋值 null),或者拼写错误等将某个变量挂载到 ...

  4. 【JavaScript】js中内存泄漏的几种情况?

    文章目录 一.是什么 二.垃圾回收机制 标记清除 引用计数 小结 三.常见内存泄露情况 参考文献 一.是什么 内存泄漏(Memory leak)是在计算机科学中,由于疏忽或错误造成程序未能释放已经不再 ...

  5. js中内存泄漏的几种情况

    内存泄漏:由于疏忽或错误造成程序未能释放已经不再使用的内存 1)意外的全局变量 解决方法:严格模式进行检测 例:函数内部定义全局变量(直接赋值) 2)定时器 不用的时候,及时清除定时器 没油及时清除的 ...

  6. js中内存泄漏与内存溢出

    内存泄漏: 占用的内存没有及时的释放从而失去控制,从而造成内存的浪费.内存泄漏多了就容易引发内存溢出. 常见的造成内存泄漏的原因: (1)没有清除闭包 // 函数执行完后, 函数内的局部变量没有释放, ...

  7. 「JavaScript灵魂之问」前端知识梳理之 JS 篇(中篇)

    对象基础 对象前置知识 /* 对象基础知识 */var teacher = {name: '张三',age: 32,sex: 'male',height: 176,weight: 130,teach: ...

  8. js日期比较大小_node.js 内存泄漏的秘密

    每日前端夜话第276篇 翻译:疯狂的技术宅 作者:Giovanny Gongora 来源:nodesource 正文共:3955 字 预计阅读时间:10分钟 一直以来,跟踪 Node.js 的内存泄漏 ...

  9. javascript内存泄漏调试工具mac_node.js 内存泄漏的秘密

    一直以来,跟踪 Node.js 的内存泄漏是一个反复出现的话题,人们始终希望对其复杂性和原因了解更多. 并非所有的内存泄漏都显而易见.但是,一旦我们确定了其模式,就必须在内存使用率,内存中保存的对象和 ...

最新文章

  1. linux什么命令只显示ip,linux ip命令
  2. 如何检查变量是否是JavaScript中的数组? [重复]
  3. 2 resize 到指定大小_阿里巴巴为什么让初始化集合时必须指定大小?
  4. 数据结构与算法--10.利益最大值
  5. 二.路径规划---二维路径规划实车实现---gmapping+amcl+map_server+move_base
  6. java读取sh脚本_linux环境下java读取sh脚本并执行
  7. iframe 父级元素查找
  8. Split的使用(C#)
  9. Kafka从上手到实践 - 实践真知:搭建单机Kafka | 凌云时刻
  10. 【车牌识别】基于matlab车牌识别【含Matlab源码 417期】
  11. 浅论照明节能的系统设计
  12. python遥感数据有偿处理_地质男转行学遥感Python——DMSP数据预处理一
  13. Java Map是否有序
  14. 百度披露被黑原委 黑客骗得邮箱
  15. 【附源码】计算机毕业设计SSM食疗养生服务平台
  16. arcgis pro发布矢量切片服务及利用arcgis api for javascript进行调用
  17. Comparable的compareTo
  18. php上传图片到mysql并显示
  19. postman接口自动化测试之判断结果是否符合预期
  20. Linaro Android 4.4.2系统下载和使用(arndale octa board)

热门文章

  1. 绘制地形图(征地篇1)-龙啸
  2. java 字符串用法_Java中的字符串用法小结
  3. windows下nginx配置php环境
  4. ida6.8如何完美显示中文
  5. 什么是动态语言和静态语言?静态语言动态语言的区别
  6. 新概念英语第一册——5-8笔记
  7. JSON Schema入门和应用
  8. 工作一个月的心得体会
  9. python学徒,Python进程路径-从学徒到大师
  10. python怎么安装pymysql_python安装PyMySQL