博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript常见内存泄露
阅读量:6001 次
发布时间:2019-06-20

本文共 2296 字,大约阅读时间需要 7 分钟。

一、全局变量引起的内存泄漏

function func(){  lmw = 123456 //lmw是全局变量,不会被释放   }

 二、闭包引起的内存泄漏

function func(){  var lmw = 123456;//闭包环境,不会被释放  function lmw2(){    //就算是一个空函数,也不会释放  }  return lmw2 //被暴露在外界,随时可能被引用}

 三、子元素存在引用引起的内存泄漏

var select = document.querySelector;var treeRef = select('#tree');var leafRef = select('#leaf');   //在COM树中leafRef是treeFre的一个子结点select('body').removeChild(treeRef);//#tree不能被回收入,因为treeRef还在

解决方法:

treeRef = null;//tree还不能被回收,因为叶子结果leafRef还在leafRef = null;//现在#tree可以被释放了

四、定时器泄露

var  timer=nullfor(var  i=0;i<5;i++){    var funcObj = {        "handle":function(){            var _this = this;            timer = setTimeout(function(){                console.log(_this)                _this.handle()            },9000)        }    }}funcObj.handle()
funcObj = null //只是改变funcObj存储在栈里的引用地址,堆里保存的真实对象不会被释放,定时器还在引用console.log(funcObj)

真正的释放还要清除定时器,再把funcObj = null

clearTimeout(timer)funcObj = nullconsole.log(funcObj)

五、循环引用

function fn() { var a = {}; var b = {}; a.pro = b; b.pro = a;} fn();
以上代码a和b的引用次数都是2,fn()执行完毕后,两个对象都已经离开环境,在标记清除方式下是没有问题的,但是在引用计数策略下,因为a和b的引用次数不为0,所以不会被垃圾回收器回收内存,如果fn函数被大量调用,就会造成内存泄露。在IE7与IE8上,内存直线上升。
IE中有一部分对象并不是原生js对象。比如,DOM和BOM中的对象就是使用C++以COM对象的形式实现的,而COM对象的垃圾回收机制采用的就是引用计数策略。因此,即使IE的js引擎采用标记清除策略来实现,但js访问的COM对象依然是基于引用计数策略的。 换句话说,只要在老IE中涉及COM对象,就会存在循环引用的问题
var element = document.getElementById("some_element");var myObject = new Object();myObject.e = element;element.o = myObject;
 
这个例子在一个DOM元素(element)与一个原生js对象(myObject)之间创建了循环引用。其中,变量myObject有一个名为e的属性指向element对象;而变量element也有一个属性名为o回指myObject。由于存在这个循环引用,即使例子中的DOM从页面中移除,它也永远不会被回收。 解决方法:
myObject.e= null;element.o = null;
再来看一个在日常开发中容易犯错的例子:
window.οnlοad=function outerFunction(){ var obj = document.getElementById("element"); obj.onclick=function innerFunction(){};};
这段代码看起来没什么问题,但是obj引用了document.getElementById(“element”),而document.getElementById(“element”)的onclick方法会引用外部环境中的变量,自然也包括obj。 解决方法:
window.οnlοad=function outerFunction(){ var obj = document.getElementById("element"); obj.onclick=function innerFunction(){}; obj=null;};
 
将变量设置为null意味着切断变量与它此前引用的值之间的连接。当垃圾回收器下次运行时,就会删除这些值并回收它们占用的内存。 在上面描述的循环引用例子,还可以理解成闭包循环引用导致的内存泄漏 当对DOM元素进行其他操作时,仍然要处处留心。只要是将JavaScript对象指定给DOM元素,就可能在旧版本IE中导致内存泄漏。jQuery只是有助于减少发生这种情况的可能性 注意:IE9+并不存在循环引用导致Dom内存泄露问题
 

转载于:https://www.cnblogs.com/liumingwang/p/6769774.html

你可能感兴趣的文章
区块链初体验
查看>>
关于手势处理
查看>>
super
查看>>
5G美洲白皮书:5G开源的现状(pdf)
查看>>
世界移动通信大会
查看>>
基于Spring Security Role过滤Jackson JSON输出内容
查看>>
从设计者的角度看 React
查看>>
js常见问题
查看>>
CentOS6系统编译部署LAMP(Linux, Apache, MySQL, PHP)环境
查看>>
71. Simplify Path
查看>>
海量大数据大屏分析展示一步到位:DataWorks数据服务对接DataV最佳实践
查看>>
PAT A1043
查看>>
JavaScript之手写Promise
查看>>
PHP_SELF变量解析和重复路径解决
查看>>
git 命令行使用(基础篇)
查看>>
在VUE中利用MQTT协议实现即时通讯
查看>>
在项目中遇到的一些bug
查看>>
Vue笔记(五)——Token&生命周期
查看>>
《前端十年心路-我把一切告诉你》的书稿大纲&问题收集
查看>>
CSS居中总结大全
查看>>