什么是内存泄漏,哪些常见操作会造成内存泄漏?

内存泄漏:指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束。

1. 介绍

JavaScript垃圾回收的机制很简单:找出不再使用的变量,然后释放掉其占用的内存,但是这个过程不是实时的,因为其开销比较大,所以垃圾回收系统(GC)会按照固定的时间间隔,周期性的执行。

怎么区分变量是否没有用,

垃圾收集器通常情况有两种方式跟踪变量

  1. 对于不再有用的变量打上标记,以备将来收回其内存 --> 标记清除(常用)
function test(){var a=10;//被标记,进入环境var b=20;//被标记,进入环境
}
test();//执行完毕之后a、b又被标记离开环境,被回收
  1. 跟踪记录每个值被引用的次数 --> 引用计数
function test(){var a={};//a的引用次数为0var b=a;//a的引用次数加1,为1var c=a;//a的引用次数加1,为2var b={};//a的引用次数减1,为1
}

2. 造成泄露的操作

  1. 意外的全局变量引起的内存泄露

一个未声明变量的引用会在全局对象中创建一个新的变量。在浏览器的环境下,全局对象就是 window,如下:

function fn(val) {b = "aaaaa";
}// 实际上等价于
function fn(val) {window.b = "aaaaa";
}// 类似的
function fn() {this.name = "zhangsan";
}
//this 指向全局对象(window)
fn();
  1. 闭包引起的内存泄露

闭包可以维持函数内局部变量,使其得不到释放。
由于是函数内定义函数,并且内部函引用了外部函数声明的变量–这就是闭包。

function fn1(){var n=1;function fn2(){//在加一个fn2当他的子集alert(n);}
return fn2();
//return出来后 他就给 window了所以一直存在内存中。因为一直在内存中,在IE里容易造成内存>泄漏
}
fn1();

2.1 还一种闭包引起的内存泄露

function bindEvent(){var obj=document.createElement("XXX");obj.οnclick=function(){//Even if it's a empty function}
}

解决之道,将事件处理函数定义在外部,解除闭包,

//将事件处理函数定义在外部
function onclickHandler(){//do something
}
function bindEvent(){var obj=document.createElement("XXX");obj.οnclick=onclickHandler;
}

或者在定义事件处理函数的外部函数中,删除对dom的引用。

//在定义事件处理函数的外部函数中,删除对dom的引用
function bindEvent(){var obj=document.createElement("XXX");obj.οnclick=function(){//Even if it's a empty function}obj=null;
}
  1. dom对象导致的内存泄漏
//1、给DOM对象添加的属性是一个对象的引用。范例:
var MyObject = {};
document.getElementById('myDiv').myProp = MyObject;

解决方法:
在window.onunload事件中写上: document.getElementById('myDiv').myProp = null;

//2、DOM对象与JS对象相互引用。范例:
function Encapsulator(element) {
this.elementReference = element;
element.myProp = this;
}
new Encapsulator(document.getElementById('myDiv'));

解决方法:
在onunload事件中写上: document.getElementById('myDiv').myProp = null;

//3、给DOM对象用attachEvent绑定事件。范例:
function doClick() {}
element.attachEvent("onclick", doClick);

解决方法:
在onunload事件中写上: element.detachEvent('onclick', doClick);

  1. 被遗忘的定时器或者回调
var someResouce=getData();
setInterval(function(){var node=document.getElementById('Node');if(node){       node.innerHTML=JSON.stringify(someRe>souce)}
},1000)

解决方法:
clearTimeout(***) 当不需要setInterval或者setTimeout时,定时器没有被clear,定时器的回调函数以及内部依赖的变量都不能被回收,造成内存泄漏。如果vue使用了定时器,需要在beforeDestroy 中做对应销毁处理。

  1. 循环引用
//反复重写同一个属性会造成内存大量占用(但关闭IE后内存会被释放)。范例:
for(i = 0; i < 5000; i++) {
hostElement.text = "asdfasdfasdf";
}

这种方式相当于定义了5000个属性!
解决方法:
其实没什么解决方法:就是编程的时候尽量避免出现这种情况

  1. 子元素存在引起的内存泄露
// 从外到内执行appendChild。这时即使调用removeChild也无法释放。范例:
var parentDiv = document.createElement("div");
var childDiv = document.createElement("div");
document.body.appendChild(parentDiv);
parentDiv.appendChild(childDiv);

解决方法:
//从内到外执行appendChild:

var parentDiv = document.createElement("div");
var childDiv = document.createElement("div");
parentDiv.appendChild(childDiv);
document.body.appendChild(parentDiv);
  1. 如果在mounted/created

钩子中使用了on,需要在beforeDestroy中做对应解绑(on,需要在beforeDestroy中做对应解绑(off)处理

beforeDestroy() {this.bus.$off('****');
}
  1. 死循环
while(1){a++;
}

解决方法:加条件

总结

  1. 减少不必要的全局变量,或者生命周期较长的对象,及时对无用的数据进行垃圾回收;
  2. 注意程序逻辑,避免“死循环”之类的 ;
  3. 避免创建过多的对象 原则:不用了的东西要及时归还。

内存泄露及避免方法

javascript基础常识问答(七)相关推荐

  1. JavaScript基础---语言基础(1)

    写在前面: 通过四篇博客把JS基础中的基础整理一下,方便自己查阅,这些内容对于实际项目开发中也许并不会在意,但是作为JS的语言基础,自觉还是应该熟悉.在完成这三篇博客(JavaScript基础---语 ...

  2. javascript基础教程_JavaScript基础教程(九)对象、类的定义与使用

    对象.类的定义与使用 对象与类是面向对象程序设计语言教学过程中不可避免需要讲解的内容之一.很多人将两者混为一谈,简单认为对象就是类,类就是对象.实际上深入分析的话,对象与类的区别还是较为明显的.本文主 ...

  3. 论文浅尝 | 通过知识到文本的转换进行知识增强的常识问答

    笔记整理:陈卓,浙江大学在读博士,主要研究方向为低资源学习和知识图谱 论文链接:https://www.aaai.org/AAAI21Papers/AAAI-10252.BianN.pdf 发表会议: ...

  4. 菜鸟学前端--javascript基础

    在学习过css相关的知识,有了前端工程师的一些基础知识.但要较好的掌握前端,必须要学习好javascript的知识. 下面将从基本语法.变量.关键字.保留字.语句.函数.BOM等角度阐释. 一.基本语 ...

  5. JavaScript基础知识与脚本语言总结

    1 Aptana插件安装 1.Aptana插件安装 <1>Aptana是一个非常强大,开源,JavaScript-focused的AJAX开发IDE. <2>它的特点包括: J ...

  6. JavaScript-百炼成仙(第1节掌握JavaScript基础1.1-1.21)

    文章目录 1.1 第一章 初入宗门 1.2 第二章 直接量 1.3 第三章 数据类型 1.4 第四章 数据类型 扩展内容: 1.5 第五章 基础考核 1.6 第六章 何老 1.7 第七章 对象数据类型 ...

  7. 【Javascript基础语法】第五周预习博客

    Javascript基础语法 前言 一.初识JavaScript 1.JS是什么 2.作用 3.浏览器执行js简介 4.Js组成 二.JS的引入方式 1.行内式 2.内部引入 3.外部引入 三.js语 ...

  8. Python基础篇(七)

    Python基础篇(七) 前言 一.元组 1.1 元组的定义 1.2 元组的常见操作 二.字典 2.1 字典的语法 2.2 字典常见操作 2.3 字典的循环遍历 三.任务清单 3.1 基础练习 3.2 ...

  9. 前端学习 之 JavaScript基础

    一. JavaScript简介 1. JavaScript的历史背景介绍 1994年,网景公司(Netscape)发布了Navigator浏览器0.9版.这是历史上第一个比较成熟的网络浏览器,轰动一时 ...

  10. 2020-web前端-JavaScript基础笔记

    ==================================================================================================== ...

最新文章

  1. windows系统中,在当前目录下打开cmd命令行的两种方法
  2. java 执行linux命令行_10个高效Linux技巧及Vim命令对比
  3. 每天一道笔试题-2012年2月16日
  4. 华为OJ平台——放苹果(典型整数划分问题)
  5. linux c之通过popen和pclose函数创建管道执行shell 运行命令使用总结
  6. ubuntu系统debootstrap的使用(构建一套基本的系统)
  7. android开发之AsyncTask的用法
  8. Jquery多选框互相内容交换
  9. android scrollview 动态添加,使用Scrollview和LinearLayout动态添加布局
  10. 数据库--Oracle
  11. 软考笔记(九)高级系统架构师/分析师:软件工程与项目管理
  12. LWN: VR和AR的开源方案
  13. 在国企的 Java 程序员是一种什么样的体验?让我来告诉你吧!
  14. CString 彻底解析
  15. 怎么寻找微信撤回的图片
  16. meta分析 1. Risk Ratio
  17. 如何重新设置苹果id密码_工信部提醒及时设置SIM卡密码,不同手机如何设置SIM卡密码?...
  18. #Paper reading#DeepInf: Social Influence Prediction with Deep Learning
  19. VSTS Overview
  20. 2019 Gartner 商业智能分析平台与数据分析报告解读

热门文章

  1. 异常:HRESULT: 0x80070057 (E_INVALIDARG) 的处理
  2. 想让游戏代入感更强,要靠他。。
  3. 集成学习算法策略 Boosting和Bagging
  4. 地震应急综合解决方案
  5. invalid index of a 0-dim tensor
  6. mysql中desc
  7. PHP地图规划骑行路径,规划结果 + 骑行路线绘制
  8. chrome鼠标手势插件
  9. Session的钝化和活化(序列化和反序列化)
  10. 常用计算机病毒表及其专杀工具,维金病毒-谁可以提供一个可以在win98平台下使用的维金病毒专杀工具(好象是....