js

浅谈JavaScript内存泄露

Posted by wml on July 11, 2018

前言

移动互联网飞速发展的时代,网页性能变得尤为重要,而关于内存泄露的问题也是开发人员最终不得不面对的问题,内存泄露导致应用程序反应迟缓、奔溃、高延迟等问题;关于内存泄露,翻阅一些文章和知识点,个人随想总结:

什么是内存泄露

内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。这个定义概括得比较全面了,简单来说,内存池中一些没有被使用或者不需要的内存没有被及时回收,导致了内存的浪费。

造成的影响

反应迟缓,崩溃,高延迟,以及其他应用问题。但并不是一定要导致这些问题才叫内存泄露,即使是1字节的内存浪费也叫内存泄露。一般是堆内存泄露,栈内存不会泄露。

1.栈内存存储的是局部变量而堆内存存储的是实体;
2.栈内存的更新速度要快于堆内存,因为局部变量的生命周期很短;
3.栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不定时的回收。

Javascript的内存管理

在JavaScript中,内存的分配和回收实现自动管理,采用标记清除的方法实现垃圾收集策略(Mark-and-sweep ),即当变量进入环境时(例如在函数中声明一个变量),将这个变量标记为“进入环境”,当变量离开环境时,则将其标记为“离开环境”。标记“离开环境”的就回收内存。虽然JavaScript会自动垃圾收集,但由于代码写法不当,造成变量一直处于“进入环境”的状态而无法被回收,也容易找出内存泄露。

JS中如何避免内存泄露

1、避免不必要的全局变量

全局变量并不会被当成垃圾回收;当全局变量用于临时存储和处理大量信息时,会增加内存消耗,所以在必须使用全局变量存储大量数据时,用完可将其设置为null或重新定义。

没有声明变量,创建了一个全局变量


function foo() {
    a = "全局变量" //实际上是window.a
}
foo();

由this创建的意外全局变量


function bar() {
    this.b = "this指向全局变量" //这里this指向了全局对象window
}
bar();

解决办法:注意变量的声明和this的使用;或者可以在函数内使用严格模式;


function foo() {
    "use strict"
    a = "报错" //这里会提示a is not undefined
    this.b = "this指向undefined"
}
foo()

也可以手动释放全局变量的内存 window.a = undefined delete window.a

不再使用的定时器或回调函数

闭包

(更新中……)