javascript常见内存泄露
一、全局变量引起的内存泄漏
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=null
for(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 = null
console.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.onload=function outerFunction(){
var obj = document.getElementById("element");
obj.onclick=function innerFunction(){};
};
这段代码看起来没什么问题,但是obj引用了document.getElementById(“element”),而document.getElementById(“element”)的onclick方法会引用外部环境中的变量,自然也包括obj。
解决方法:
window.onload=function outerFunction(){
var obj = document.getElementById("element");
obj.onclick=function innerFunction(){};
obj=null;
};
将变量设置为null意味着切断变量与它此前引用的值之间的连接。当垃圾回收器下次运行时,就会删除这些值并回收它们占用的内存。
在上面描述的循环引用例子,还可以理解成闭包循环引用导致的内存泄漏
当对DOM元素进行其他操作时,仍然要处处留心。只要是将JavaScript对象指定给DOM元素,就可能在旧版本IE中导致内存泄漏。jQuery只是有助于减少发生这种情况的可能性
注意:IE9+并不存在循环引用导致Dom内存泄露问题
javascript常见内存泄露的更多相关文章
- javascript js 内存泄露
JavaScript 内存泄露 1.什么是闭包.以及闭包所涉及的作用域链这里就不说了. 2.JavaScript垃圾回收机制 JavaScript不需要手动地释放内存,它使用一种自动垃圾回收机制(ga ...
- 如何避免JavaScript的内存泄露及内存管理技巧
发表于谷歌WebPerf(伦敦WebPerf集团),2014年8月26日. 高效的JavaScript Web应用必须流畅,快速.与用户交互的任何应用程序,都需要考虑如何确保内存有效使用,因为如果 ...
- 【javascript】内存泄露及其解决办法
1.内存泄露:一般由于开发者使用不当导致不用的内存没有被操作系统或者空闲内存池回收释放. 2.造成内存泄露的常见原因: 1) 意外的全局变量引起的内存泄露 2)闭包引起的内存泄露 闭包可以维持函数内局 ...
- JavaScript:内存泄露、性能调优
1.在进行JS内存泄露检查之前,先要了解JS的内存管理: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Manageme ...
- javascript js 内存泄露工具使用
javascript内存泄露工具使用 原文:http://lanhy2000.blog.163.com/blog/static/43678608201121472644851/ 2011-03-14 ...
- Android常见内存泄露,学会这六招优化APP性能
很多开发者都知道,在面试的时候会经常被问到内存泄露和内存溢出的问题. 1.内存溢出(Out Of Memory,简称 OOM),通俗理解就是内存不够,即内存占用超出内存的空间大小. 2.内存泄漏(Me ...
- Android 常见内存泄露 & 解决方案
前言 内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃 (OOM) 等严重后果. 那什么情况下不能被 ...
- JS高程中的垃圾回收机制与常见内存泄露的解决方法
起因是因为想了解闭包的内存泄露机制,然后想起<js高级程序设计>中有关于垃圾回收机制的解析,之前没有很懂,过一年回头再看就懂了,写篇博客与大家分享一下. #内存的生命周期: 分配你所需要的 ...
- Android常见内存泄露
前言 对于内存泄漏,我想大家在开发中肯定都遇到过,只不过内存泄漏对我们来说并不是可见的,因为它是在堆中活动,而要想检测程序中是否有内存泄漏的产生,通常我们可以借助LeakCanary.MAT等工具来检 ...
随机推荐
- windwos下基于exp的提权
00x1: 本文是基于windwos 补丁的漏洞提权. 其实是一件很简单的工作:如果看成数据库的3张表分别是: 未打补丁表, 补丁漏洞表, 漏洞利用提权程序表. 为一一对应关系,所以就是资源的掌握,以 ...
- Shiro+CAS
参考链接: CAS实现单点登录SSO执行原理探究:http://blog.csdn.net/javaloveiphone/article/details/52439613 单点登录CAS技术概述:ht ...
- 深入理解Tomcat
简介 tomcat是一个web服务器,运行jsp和servlet,使用HTTP与客户端(通常是浏览器)进行通信. 构成 下图是tomcat的架构,可以看出:核心内容是Connector和Contain ...
- 使用httpClient发送post请求连接restful接口
public static String httpPost(String url,String arg){ InputStream is; BufferedReader br; StringBuild ...
- 清除eclipse,STS workspace历史记录
记一下 打开eclipse下的/configuration/.settings目录 修改文件org.eclipse.ui.ide.prefs文件 把RECENT_WORKSPACES这项修改为你需要的 ...
- tomcat 部署swagger 请求到后端乱码
问题: @ApiOperation(value = "", notes = "查看关键词列表") @ResponseBody @RequestMapping(v ...
- 同步锁Lock(互斥锁)
同步锁作用: 在我当前包含(lock.acquire() 和 lock.release()之间 )的代码没有执行完成,不进行线程切换,必须等我执行完了,下一个线程才能继续执行(为什么要用同步锁,假如我 ...
- jeecg开源项目的IDEA的部署
JEECG采用了SpringMVC + Hibernate + Minidao(类Mybatis) + Easyui(UI库)+ Jquery + Boostrap + Ehcache + Redis ...
- python 列表 list的基本操作
一,Python 的列表数据类型包含更多的方法. 这里是所有的列表对象方法: list.append(x) 把一个元素添加到链表的结尾,相当于 a[len(a):] = [x] . list.exte ...
- springboot整合zookeeper
在springboot中所有的整合都是以bean的形式注入对象,从数据库coon.redis conn.再到整合的zookeeper,依然是依照bean注入连接对象,通过zookeeper api对z ...