JS中4种常见的内存泄漏
一、什么是内存泄漏
本质上讲,内存泄漏是当一块内存不再被应用程序使用的时候,由于某种原因,这块内存没有返还给操作系统或空闲内存池的现象。
二、几种常见的内存泄漏
1、意外的全局变量
一个未声明变量的引用会在全局对象中创建一个新的变量。在浏览器的环境下,全局对象就是window,也就是说:
function foo(arg) {bar = "this is a hidden global variable"; }
实际上是:
function foo(arg) {window.bar = "this is an explicit global variable"; }
上面代码中,如果bar是一个应该指向foo函数作用域内变量的引用,但忘记使用var来声明这个变量,这时就相当于创建了一个全局变量。
另外一种偶然创建全局变量的方式如下:
function foo() {this.variable = "potential accidental global"; } foo();
上面代码中,foo函数再全局作用域中被调用,因此this指向window
全局变量的注意事项:
如果需要全局变量来存储很多数据,必须确保在使用过后将它设置为null或重新为他赋值。
常见的和全局变量相关的引发内存消耗增长的原因是缓存。缓存存储着可复用的数据。
为了让这种做法更高效,必须为缓存的容量规定一个上界。由于缓存不能被及时回收的缘故,缓存无限制地增长会导致很高的内存消耗。
2、闭包引起的内存泄漏
闭包可以使变量常驻内存,但如果使用不当就会在成内存泄漏
var theThing = null; var replaceThing = function () {var originalThing = theThing;var unused = function () {if (originalThing)console.log("hi");};theThing = {longStr: new Array(1000000).join('*'),someMethod: function () {console.log(someMessage);}}; }; setInterval(replaceThing, 1000);
上面代码中,每次调用 replaceThing
时,theThing
都会得到新的包含一个大数组和新的闭包(someMethod
)的对象。
同时,没有用到的那个变量持有一个引用了 originalThing
(replaceThing
调用之前的 theThing
)闭包。
关键的问题是每当在同一个父作用域下创建闭包作用域的时候,这个作用域是被共享的。在这种情况下,someMethod
的闭包作用域和 unused
的作用域是共享的。
unused
持有一个 originalThing
的引用。尽管 unused
从来没有被使用过,someMethod
可以在 theThing
之外被访问。
而且 someMethod
和 unused
共享了闭包作用域,即便 unused
从来都没有被使用过,它对 originalThing
的引用还是强制它保持活跃状态(阻止它被回收)。
当这段代码重复运行时,将可以观察到内存消耗稳定地上涨,并且不会因为 GC 的存在而下降。
本质上来讲,创建了一个闭包链表(根节点是 theThing
形式的变量),而且每个闭包作用域都持有一个对大数组的间接引用,这导致了一个巨大的内存泄露。
3、DOM之外的引用
var elements={ button: document.getElementById("button"), image: document.getElementById("image"), text: document.getElementById("text") }; function doStuff(){ image.src="http://some.url/image"; button.click(): console.log(text.innerHTML) } function removeButton(){ document.body.removeChild(document.getElementById('button')) }
2、被遗漏的定时器和回调函数
var someResouce=getData(); setInterval(function(){ var node=document.getElementById('Node'); if(node){ node.innerHTML=JSON.stringify(someResouce) } },1000)
上面代码中, 如果 id 为 Node 的元素从 DOM 中移除, 该定时器仍会存在, 同时, 因为回调函数中包含对 someResource 的引用, 定时器外面的 someResource 也不会被释放。
三、怎样避免内存泄漏
1)减少不必要的全局变量,或者生命周期较长的对象,及时对无用的数据进行垃圾回收;
2)注意程序逻辑,避免“死循环”之类的 ;
3)避免创建过多的对象 原则:不用了的东西要及时归还。
JS中4种常见的内存泄漏相关推荐
- Dreamwear如何创建javascript_内存管理+如何处理4种常见的内存泄漏
JavaScript是如何工作的:内存管理+如何处理4种常见的内存泄漏 潮水自会来去,但心志得坚若磐石.即便成不了那根定海神针,也至少不是那随意被拍上岸的野鬼游魂.by 一枚热汤圆 几周前,我们开始了 ...
- JavaScript内存管理机制以及四种常见的内存泄漏解析
转自:http://geek.csdn.net/news/detail/238898 原文:How JavaScript works: memory management + how to handl ...
- js中一种常见条件判断if(var)的坑
在处理js代码判断真假时经常会这么写. //从某个地方获取的值. var vale = fun(......... );if(!value){进入这里表示value的布尔值为false } 我们知道, ...
- 手撕前端面试题(Javascript~事件委托、数组去重、合法的URL、快速排序、js中哪些操作会造成内存泄漏......
前端的那些基本标签
- JS中常见的内存泄漏及识别方式
JavaScript常见的内存泄漏及识别方式 1.什么是内存 2.什么是内存泄漏 3.内存泄漏导致的后果 4.常见的内存泄漏 (1)全局变量引起的内存泄漏 (2)闭包引起的内存泄漏 (3)被遗忘的定时 ...
- 精华阅读第 13 期 |常见的八种导致 APP 内存泄漏的问题 1
2019独角兽企业重金招聘Python工程师标准>>> 本期是移动开发精英俱乐部的第13期文章,都是以技术为主,所以这里就不过多的进行赘述了,我们直接看干货内容吧!本文系ITOM管理 ...
- 5 个 Android 开发中比较常见的内存泄漏问题及解决办法
Android开发中,内存泄漏是比较常见的问题,有过一些Android编程经历的童鞋应该都遇到过,但为什么会出现内存泄漏呢?内存泄漏又有什么影响呢? 在Android程序开发中,当一个对象已经不需要再 ...
- java内部类内存泄漏,Android中常见的内存泄漏和解决方案
什么是内存泄漏? 简单点说,就是指一个对象不再使用,本应该被回收,但由于某些原因导致对象无法回收,仍然占用着内存,这就是内存泄漏. 为什么会产生内存泄漏,内存泄漏会导致什么问题? 相比C++需要手动去 ...
- android内存池,两种常见的内存管理方法:堆和内存池
描述 本文导读 在程序运行过程中,可能产生一些数据,例如,串口接收的数据,ADC采集的数据.若需将数据存储在内存中,以便进一步运算.处理,则应为其分配合适的内存空间,数据处理完毕后,再释放相应的内存空 ...
最新文章
- 纳米孔测序高错误区域恢复率高达99%,肖传乐/刘奕志/王建新等在Nature子刊发表新校正组装算法
- DP mixture model
- nginx部署laravel需要修改的配置
- Java笔记-IO流的运用
- 前端学习(1368):app.use使用
- 信息学奥赛一本通(1094:与7无关的数)
- 微信小程序开发需要了解的三个内核技术
- Java Web(十) JDBC的增删改查,C3P0等连接池,dbutils框架的使用
- linux与linux传文件乱码,关于Linux与windows传递文件乱码问题
- left join on or 优化_pandas中merge/join有什么区别?
- C#重写WebBrowser组件,禁止跳转到IE新窗口、脚本错误
- ruby DBI安装使用指南
- linux安装jdk(二)
- n9 android模拟器,Android软件将兼容诺基亚N9
- 一元初始,森罗万象:5G角逐已被荣耀拉开序幕
- 《人机交互技术》 第五章 界面设计
- 硬回车、软回车、java转义字符
- Unity 贴花/喷漆功能的原理、Projector组件的原理与优化
- java 回归分析_机器学习的回归是什么
- 湖北移动M411A_ZN-S905L3AB-UWE5621DS原机制作语音线刷包