Javascript的内存泄漏分析
作为程序员(更高大尚的称谓:研软件研发)的我们,无论是用Javascript,还是.net, java语言,肯定都遇到过内存泄漏的问题。只不过他们都有GC机制来帮助程序员完成内存回收的事情,如果你是C++开发者(你懂的)。。。。。,如果你是前端开发者,肯定在使用Javascript(你或者会说,Js是世界上最棒的语言),但我这里也得告诉你,Js的内存泄漏会来得更为突然,或者让你都无法察觉。本文就带大家领略一下Js的风骚:
一、模块化引起的内存泄漏
代码如下:
// module date.js
let date = null;
export default {
init () {
date = new Date();
}
} // main.js
import date from 'date.js';
date.init();
上述是我们在现代前端工程方案中常见的代码格式,写一个模块,然后导出这一个模块。这里你应该知道date.js中的date是静态的(也就是你在N处导入date.js这个模块),但他们的date这个变量是共享的,一处改变,其他地方也对应发生变化。
二、假OOP范式引起的内存泄漏
在这里我为什么叫他假OOP呢,原因是这代码是想实现OOP范式却让自己掉到坑里去了,先上代码:
var fun = function(arg){
this.sarg = arg;
var self = this;
return function(){
console.log(self.sarg);
}
}
var fn = new fun('data arg');
fn();
首先,定义fun这个函数变量,然后返回一个function(这可以说就是典型的闭包)。闭包函数内引用外面的this对象(var self = this)。
然后,通过new的方式调用fun,返回值用fn接受,这里谁都知道返回的是一个函数,所以可以括号运算符进行执行。
2.1 利用chrome的memory面板进行分析
定位到memory面板,然后刷新页面,再单击下图中所示的 'collect garbage'图标(也就是像回收站的图标),强制进行一次gc的回收,这样可以确保我们分析的对象就是可以存在内存泄漏的对象(至少他们是gc不可回收的对象)。
此图是上述代码片段在chrome浏览器中执行完成后,不能被gc回收的内存变量。
2.2 我认为的原因
先贴出发生内存泄漏的代码
var fun = function(arg){
this.sarg = arg; //内存泄漏
var self = this;//内存泄漏
return function(){
console.log(self.sarg);//内存泄漏
}
}
var fn = new fun('data arg'); //内存泄漏
fn();
我认为的原因有以下几点:
1. 使用new运算符,他会创建一个对象,然后执行构造函数,并将构造函数对应的prototype(也就是原型)复制到新的对象上。
2. 上述new出来的新对象,在执行构造函数时,其this就指向了这个new出来的新对象
3. 然后上述代码在构造函数中又返回了一个函数,且函数中引用了new出来的新对象,返回函数赋值给了fn变量
4. 最的执行fn变量,正确输出我们想要的内容,这样程序就跑了(可以,我们new出来的新对象,没有人管也了,所以他就泄漏了)。
2.3 总结:
因为正常情况下,我们对一个function进行new操作的时候,在构造函数内是不会进行返回的,其实这个时候new操作默认给你返回的就是构造函数中的this对象。上述代码不建议出现在项目代码中,这是典型的错误写法,并示例只是为了演示泄漏。
三、DOM事件引起的内存泄漏
如果你是Jquery的忠粉,这部分可能对你有帮助,先上代码:
//html:
<input type="file" id="file" />
<button type="button" onclick="remove()" >but</button> //js:
var file = document.getElementById("file");
file.addEventListener('change',function(event){
console.log(event.target.value);
});
function remove(){
file.remove();
}
首先我们在html中写两个标签,一个是file、一个是button;然后在js中对file标签绑定了change事件,然后对button绑定一个remove方法,用于移除file标签。
3.1 内存泄漏分析
在我们执行了remove方法后,然后收集内存分析:
我们还按照示例二相同的操作,打开memory面板,然后执行一次GC回收后收集内存数据,然后查看Detached Dom tree(这就表示与DOM树失去联系的对象),然后我们把鼠标移动到native上,就会显示内存泄漏的代码位置。
Jquery忠粉们可以注意了,无论你是用的bind还是on进行事件的绑定,如果你在移除这些DOM元素前,没有进行相应的unbind或是off操作,那么恭喜你,内存一定泄漏了。
Javascript的内存泄漏分析的更多相关文章
- 关于Javascript的内存泄漏问题的整理稿
写了好长时间javascript小功能模块,从来没有关注过内存泄漏问题.记得以前写C++程序的时候,内存泄漏是个严重的问题,我想是时候关注一下了.网上找了篇文章,Mark一下.原文地址:http:// ...
- Java内存泄漏分析与解决方案
Java内存泄漏是每个Java程序员都会遇到的问题,程序在本地运行一切正常,可是布署到远端就会出现内存无限制的增长,最后系统瘫痪,那么如何最快最好的检测程序的稳定性,防止系统崩盘,作者用自已的亲身经历 ...
- Android内存泄漏分析及调试
尊重原创作者,转载请注明出处: http://blog.csdn.net/gemmem/article/details/13017999 此文承接我的另一篇文章:Android进程的内存管理分析 首先 ...
- Android 内存泄漏分析与解决方法
在分析Android内存泄漏之前,先了解一下JAVA的一些知识 1. JAVA中的对象的创建 使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象 垃圾回收器回收非存活的对象,并释放对应的内 ...
- Java内存泄漏分析系列之五:常见的Thread Dump日志案例分析
原文地址:http://www.javatang.com 症状及解决方案 下面列出几种常见的症状即对应的解决方案: CPU占用率很高,响应很慢 按照<Java内存泄漏分析系列之一:使用jstac ...
- Java内存泄漏分析系列之二:jstack生成的Thread Dump日志结构解析
原文地址:http://www.javatang.com 一个典型的thread dump文件主要由一下几个部分组成: 上图将JVM上的线程堆栈信息和线程信息做了详细的拆解. 第一部分:Full th ...
- Android内存泄漏分析实战
内存泄漏简单介绍 java能够保证当没有引用指向对象的时候,对象会被垃圾回收器回收.与c语言自己申请的内存自己释放相比,java程序猿轻松了非常多.可是并不代表java程序猿不用操心内存泄漏.当jav ...
- (转)Android内存泄漏分析及调试
http://blog.csdn.net/gemmem/article/details/13017999 此文承接我的另一篇文章:Android进程的内存管理分析 首先了解一下dalvik的Ga ...
- 使用Eclipse Memory Analyzer进行内存泄漏分析三部曲
源地址:http://seanhe.iteye.com/blog/898277 一.准备工作 分析较大的dump文件(根据我自己的经验2G以上的dump文件就需要使用以下介绍的方法,不然mat会出现 ...
随机推荐
- flume原理
1. flume简介 flume 作为 cloudera 开发的实时日志收集系统,受到了业界的认可与广泛应用.Flume 初始的发行版本目前被统称为 Flume OG(original generat ...
- 对Python这门课程的理解。
这门课程是现在热门,对之后的就业和利用的帮助还是很大的. 希望能学完整本书并且能学以致用,而不是单单只获得理论知识. 学完之后能用于数据库.大数据处理.图形编程等等
- mac 登录亚马逊云服务器报错:Permission denied (publickey).
申请的亚马逊云服务器EC2,实例为ubuntu系统 一.打开终端,定位到放置密钥的文件夹: 二.确保私有秘钥不是公开可见的: p.p1 { margin: 0.0px 0.0px 0.0px 0.0p ...
- MySQL性能调优——锁定机制与锁优化分析
针对多线程的并发访问,任何一个数据库都有其锁定机制,它的优劣直接关系着数据的一致完整性与数据库系统的高并发处理性能.锁定机制也因此成了各种数据库的核心技术之一.不同数据库存储引擎的锁定机制是不同的,本 ...
- 由于github仓库中提前建立readme文件,导致git push报错error: failed to push some refs to 'git@github.com:
$ git push -u origin master To git@github.com:xxx/xxx.git ! [rejected] master -> master (fetch fi ...
- SSM-MyBatis-14:Mybatis中智能标签
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 谈论到智能,有什么要想的没有? 我下面放张图 相信都见过这个吧,你在之前没有学习过框架的时候怎么写的,动态sq ...
- onCreate和onStart谁的开销大?
大家都知道,onCreate方法在创建的时候开始调用一些方法来获取资源方面的东西,这个是在程序运行之初才执行的,一个完整的生命周期中,它只执行了一次,不被onDestroy掉,就一直不调用,而onSt ...
- Graphviz--图形绘制工具
可以试试ProcessOn.com, 一个专业在线画流程图的工具,使用Chrome&Firefox浏览器,支持快捷键,非常方便.快捷键如下:Ctrl+A 全选,当移动整张图时非常方便Ctrl+ ...
- python3中用HTMLTestRunner.py报ImportError: No module named 'StringIO'解决办法
.原因是官网的是python2语法写的,看官手动把官网的HTMLTestRunner.py改成python3的语法: 参考:http://bbs.chinaunix.net/thread-415474 ...
- Doctype作用?标准模式与兼容模式各有什么区别?
Doctype作用?标准模式与兼容模式各有什么区别? DOCTYPE是document type(文档类型)的简写,用来告诉浏览器的解析器使用哪种HTML或XHTML规范解析页面.DOCTYPE不存在 ...