前言

内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。这里就讲一些常见会带来内存泄露的原因。

0. 全局变量

JavaScript自由的其中一种方式是它可以处理没有声明的变量:一个未声明的变量的引用在全局对象中创建了一个新变量。在浏览器的环境中,全局对象是window。
 function foo(){
name = '前端曰';
}
// 其实是把name变量挂载在window对象上
function foo(){
window.name = '前端曰';
} // 又或者
function foo(){
this.name = '前端曰';
}
foo() // 其实这里的this就是指向的window对象

这样无意中一个意外的全局变量就被创建了,为了阻止这种错误发生,在你的Javascript文件最前面添加 'use strict;' 。这开启了解析JavaScript的阻止意外全局的更严格的模式。或者自己注意好变量的定义!

1. 循环引用

在js的内存管理环境中,对象 A 如果有访问对象 B 的权限,叫做对象 A 引用对象 B。引用计数的策略是将“对象是否不再需要”简化成“对象有没有其他对象引用到它”,如果没有对象引用这个对象,那么这个对象将会被回收 。

 function func() {
let obj1 = {};
let obj2 = {}; obj1.a = obj2; // obj1 引用 obj2
obj2.a = obj1; // obj2 引用 obj1
}

当函数 func 执行结束后,返回值为 undefined,所以整个函数以及内部的变量都应该被回收,但根据引用计数方法,obj1 和 obj2 的引用次数都不为 0,所以他们不会被回收。要解决循环引用的问题,最好是在不使用它们的时候手工将它们设为空。

解决方案:obj1 和 obj2 都设为 null 。

2. 闭包

闭包:匿名函数可以访问父级作用域的变量。

 var names = (function(){
var name = 'js-say';
return function(){
console.log(name);
}
})()

闭包会造成对象引用的生命周期脱离当前函数的上下文,如果闭包如果使用不当,可以导致环形引用(circular reference),类似于死锁,只能避免,无法发生之后解决,即使有垃圾回收也还是会内存泄露。

3. 被遗忘的延时器/定时器

在我们的日常需求中,可能会经常试用到 setInterval/setTimeout ,但是使用完之后通常忘记清理。

 var someResource = getData();
setInterval(function() {
var node = document.getElementById('Node');
if(node) {
// 处理 node 和 someResource
node.innerHTML = JSON.stringify(someResource));
}
}, );

setInterval/setTimeout 中的 this 指向的是window对象,所以内部定义的变量也挂载到了全局;if 内引用了 someResource 变量,如果没有清除 setInterval/setTimeout 的话someResource 也得不到释放;同理其实 setTimeout也一样。所以我们用完需要记得去 clearInterval/clearTimeout。

4. DOM引起的内存泄露

  • 未清除DOM引用
 var refA = document.getElementById('refA');
document.body.removeChild(refA);
// #refA不能回收,因为存在变量refA对它的引用。将其对#refA引用释放,但还是无法回收#refA。

解决方案:refA = null 。

  • DOM对象添加的属性是一个对象的引用
var MyObject = {};
document.getElementById('myDiv').myProp = MyObject;

解决方案:在页面 onunload 事件中释放 document.getElementById('myDiv').myProp = null; 。

DOM被删除或清空没有清楚绑定事件这种情况应该是比较常见的,同时也应该是比较容易被忽略的。

  • 给DOM对象绑定事件
 var btn = document.getElementById("myBtn");
btn.onclick = function(){
document.getElementById("myDiv").innerHTML = "wechat: js-say";
} document.body.removeChild(btn);
btn = null;

这里把DOM移除了,但是绑定的事件仍没被移除,会引起内存泄露所以需要清除事件。

 var btn = document.getElementById("myBtn");
btn.onclick = function(){
btn.onclick = null;
document.getElementById("myDiv").innerHTML = "wechat: js-say";
} document.body.removeChild(btn);
btn = null;

常见的Java Script内存泄露原因及解决方案的更多相关文章

  1. java造成内存泄露原因

    一.Java内存回收机制  不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址.Java中对象是采用new或者反射的方法创建的,这些对象的创建都是在堆(He ...

  2. Java内存泄露原因详解

    一.Java内存回收机制 不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址.Java中对象是采用new或者反射的方法创建的, 这些对象的创建都是在堆(He ...

  3. java中内存泄露有几种?如何分析泄露原因

    一.Java内存回收机制 不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址.Java中对象是采用new或者反射的方法创建的,这些对象的创建都是在堆(Hea ...

  4. .Net内存泄露原因及解决办法

    .Net内存泄露原因及解决办法 1.    什么是.Net内存泄露 (1).NET 应用程序中的内存 您大概已经知道,.NET 应用程序中要使用多种类型的内存,包括:堆栈.非托管堆和托管堆.这里我们需 ...

  5. 解决Net内存泄露原因

    Net内存泄露原因及解决办法 https://blog.csdn.net/changtianshuiyue/article/details/52443821 什么是.Net内存泄露 (1).NET 应 ...

  6. java的内存泄露是如何发生的,如何避免和发现

    java的垃圾回收与内存泄露的关系:[新手可忽略不影响继续学习] 马克-to-win:上一节讲了,(i)对象被置成null.(ii)局部对象(无需置成null)当程序运行到右大括号.(iii)匿名对象 ...

  7. Java的内存泄露

    Java的内存泄露 1.静态集合类引起内存泄漏 像HashMap.Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,他们所引用的所有的对象Object也不能被释放,因为他们 ...

  8. Android开发笔记——常见BUG类型之内存泄露与线程安全

    本文内容来源于最近一次内部分享的总结,没来得及详细整理,见谅. 本次分享主要对内存泄露和线程安全这两个问题进行一些说明,内部代码扫描发现的BUG大致分为四类:1)空指针:2)除0:3)内存.资源泄露: ...

  9. 记一次Java的内存泄露分析

    当前环境 jdk == 1.8 httpasyncclient == 4.1.3 代码地址 git 地址:https://github.com/jasonGeng88/java-network-pro ...

随机推荐

  1. try catch影响Spring事务吗?

    对于这个问题有两种情况: 1.catch只打印异常,不抛出异常 try { 数据库做添加订单表; /; 数据库减少库存; }catch (Exception e){ e.printStackTrace ...

  2. 微信小程序,获取点击元素的索引值index

    1.需求说明 点击 “加号图片” 上传图片,需要知道点击的是第几个图片,动态的修改src数组,这里图片用的 wx:for 循环出来的 2.遇到问题 按照官方最新文档循环的方式,索引值是以  wx:fo ...

  3. 验证DNS解析失败:解决办法之一

    今天晚上练习简单的DNS解析验证: 环境是在一台虚拟机上搭建,另一台虚拟机验证,步骤如下: 虚拟机A: 1.安装软件包 bind  和bind-chroot[root@svr7 ~]# yum -y ...

  4. Random和ArrayList的应用

    /*Random类应用与Math类应用,创建一个类, * 1)分别用Random类和Math.random()方法生成随机数. * 2) 把Math.random()方法生成的随机数,转换成1-100 ...

  5. plotting and saving over line in paraView

    probe -- provides the field values in a particular location in space To save plotoverline to csv fil ...

  6. sublime3注册码

    TwitterInc User License EA7E 1D77F72E 390CDD93 4DCBA022 FAF60790 61AA12C0 A37081C5 D0316412 4584D136 ...

  7. [洛谷P1114] “非常男女”计划

    题目描述 近来,初一年的XXX小朋友致力于研究班上同学的配对问题(别想太多,仅是舞伴),通过各种推理和实验,他掌握了大量的实战经验.例如,据他观察,身高相近的人似乎比较合得来. 万圣节来临之际,XXX ...

  8. Ubuntu中PPA源是什么

    以下内容转自https://imcn.me/ppa: PPA是Personal Package Archives首字母简写.翻译为中文意思是:个人软件包文档 只有Ubuntu用户可以用,而所有的PPA ...

  9. [Algorithm] Determine if two strings are an anagram

    The anagram test is commonly used to demonstrate how an naive implementation can perform significant ...

  10. HDUJ 2070 Fibbonacci Number

    Fibbonacci Number Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...