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操作,那么恭喜你,内存一定泄漏了。

原文地址:https://www.cnblogs.com/cqhaibin/p/9280753.html

时间: 2024-11-05 11:00:45

Javascript的内存泄漏分析的相关文章

Node.js内存泄漏分析

在极客教育出版了一个视频是关于<Node.js 内存泄漏分析>,本文章主要是从内容上介绍如何来处理Node.js内存异常问题.如果希望学习可前往极客学院: 本文章的关键词 - 内存泄漏 - 内存泄漏检测 - GC分析 - memwatch 文章概要 由于内存泄漏在Node.js中非常的常见,可能在浏览器中应用javascript时,对于其内存泄漏不是特别敏感,但作为服务器语言运行时,你就不得不去考虑这些问题.由于很小的逻辑可能导致服务器运行一天或者一个星期甚至一个月才会让你发现内存不断上涨,而

View的post方法导致的内存泄漏分析

简述: 写这篇文章的缘由是最近项目中查内存泄漏时,发现最终原因是由于异步线程调用View的的post方法导致的. 为何我会使用异步线程调用View的post方法,是因为项目中需要用到很多复杂的自定义布局,需要提前解析进入内存,防止在主线程解析导致卡顿,具体的实现方法是在Application启动的时候,使用异步线程解析这些布局,等需要使用的时候直接从内存中拿来用. 造成内存泄漏的原因,需要先分析View的post方法执行流程,也就是文章前半部分的内容 文章内容: View#post方法作用以及实

android 内存泄漏分析技巧

java虚拟机运行一般都有一个内存界限,超过这个界限,就会报outofmemory.这个时候一般都是存在内存泄漏.解决内存泄漏问题,窃以为分为两个步骤:分析应用程序是否真的有内存泄漏,找到内存泄漏的地方.这两个步骤都不是一般意义上的调试,直接打log,断点调试都不是太给力.动脑筋想一想,内存问题应该在很多地方上都会出现,这么常见的问题应该是有工具的.android现在更可以说是一个生态系统,当然也有很多开发辅助工具.在前面的两个步骤中都有很强大的武器,熟练的掌握这些利器,分析问题就会事半功倍.

使用Eclipse Memory Analyzer进行内存泄漏分析三部曲

源地址:http://seanhe.iteye.com/blog/898277 一.准备工作 分析较大的dump文件(根据我自己的经验2G以上的dump文件就需要使用以下介绍的方法,不然mat会出现oom)需要调整虚拟机参数 找个64位的系统在MemoryAnalyzer.ini设置-Xmx2g 如果是32位的xp可以使用下面的方法进行尝试: 安装jrockit 6.0的JDK mat使用jrockit的jdk来启动 Java代码   -vm D:/Program Files/Java/jroc

Java内存泄漏分析与解决方案

Java内存泄漏是每个Java程序员都会遇到的问题,程序在本地运行一切正常,可是布署到远端就会出现内存无限制的增长,最后系统瘫痪,那么如何最快最好的检测程序的稳定性,防止系统崩盘,作者用自已的亲身经历与各位网友分享解决这些问题的办法. 作为Internet最流行的编程语言之一,Java现正非常流行.我们的网络应用程序就主要采用Java语言开发,大体上分为客户端.服务器和数据库三个层次.在进入测试过程中,我们发现有一个程序模块系统内存和CPU资源消耗急剧增加,持续增长到出现java.lang.Ou

100%正确的内存泄漏分析工具 &#160; &#160; &nbsp; --------tMemMonitor (TMM)

C/C++由于灵活.高效的优点一直以来都是主流的程序设计语言之一,但是其内存的分配与释放均由程序员自己管理,当由于疏忽或错误造成程序未能释放不再使用的内存时就会造成内存泄漏.在大型.复杂的应用程序中,内存泄漏往往是最常见的问题,因而及时解决内存泄漏非常必要.tMemMonitor (TMM)作为一个专业.准确.易用的内存泄漏分析工具,可以帮助C/C++程序员迅速地解决内存泄漏这个令人头疼的问题. TMM下载地址: 一.开发背景 目前市面上已有一些Windows平台下的内存泄漏动态检测工具,比如U

Android内存泄漏分析实战

内存泄漏简单介绍 java能够保证当没有引用指向对象的时候,对象会被垃圾回收器回收.与c语言自己申请的内存自己释放相比,java程序猿轻松了非常多.可是并不代表java程序猿不用操心内存泄漏.当java程序发生内存泄漏的时候往往具有隐蔽性.因此要借助一些专业的平台资源去保证安全性,比如能够通过加密实现. 定义 引用百度百科的定义:"用动态存储分配函数动态开辟的空间,在使用完成后未释放,结果导致一直占领该内存单元. 直到程序结束".从程序员的角度来看"内存泄漏",事实

内存泄漏分析工具tMemMonitor (TMM)使用简介

C/C++由于灵活.高效的优点一直以来都是主流的程序设计语言之一,但是其内存的分配与释放均由程序员自己管理,当由于疏忽或错误造成程序未能释放不再使用的内存时就会造成内存泄漏.在大型.复杂的应用程序中,内存泄漏往往是最常见的问题,因而及时解决内存泄漏非常必要.tMemMonitor (TMM)作为一个专业.准确.易用的内存泄漏分析工具,可以帮助C/C++程序员迅速地解决内存泄漏这个令人头疼的问题. TMM下载地址:http://download.csdn.net/download/tmemmoni

关于Javascript的内存泄漏问题的整理稿

写了好长时间javascript小功能模块,从来没有关注过内存泄漏问题.记得以前写C++程序的时候,内存泄漏是个严重的问题,我想是时候关注一下了.网上找了篇文章,Mark一下.原文地址:http://www.blogjava.net/tim-wu/archive/2006/05/29/48729.html 常规循环引用内存泄漏和Closure内存泄漏 要了解javascript的内存泄漏问题,首先要了解的就是javascript的GC原理. 我记得原来在犀牛书<JavaScript: The D