一、内存的周期和回收机制
分配内存----->使用内存----->释放内存
1.JS 环境中分配的内存有如下声明周期:
- 内存分配:当我们声明变量、函数、对象的时候,系统会自动为他们分配内存
- 内存使用:即读写内存,也就是使用变量、函数等
- 内存回收:使用完毕,由垃圾回收机制自动回收不再使用的内存
2.JS 的内存回收
JS 有自动垃圾回收机制,那么这个自动垃圾回收机制的原理是什么呢? 其实很简单,就是找出那些不再继续使用的值,然后释放其占用的内存。
大多数内存管理的问题都在这个阶段。 在这里最艰难的任务是找到不再需要使用的变量。
①不再需要使用的变量也就是生命周期结束的变量,局部变量,局部变量只在函数的执行过程中存在, 当函数运行结束,变量就没有存在的必要了,没有其他引用(闭包),那么该变量会被回收。
②对于全局变量,很难判断什么时候不用这些变量,无法正常回收,所以全局变量的生命周期直至浏览器卸载页面才会结束,也就是说全局变量不会被当成垃圾回收。
因为自动垃圾回收机制的存在,开发人员可以不关心也不注意内存释放的有关问题,但对无用内存的释放这件事是客观存在的。 不幸的是,即使不考虑垃圾回收对性能的影响,目前最新的垃圾回收算法,也无法智能回收所有的极端情况。
二、内存泄露(内存浪费)
官方解释:内存泄漏(memory leak)是指程序中己动态分配的内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
通俗点就是指由于疏忽或者错误造成程序未能释放已经不再使用的内存,不再用到的内存却没有及时释放,从而造成内存上的浪费。
如何避免:
①尽量少使用全局变量。使用完进行释放内存,可以设置值为null进行内存释放
②在使用闭包的时候,就会造成严重的内存泄漏,因为闭包中的局部变量,会一直保存在内存中,
所以不要大量使用闭包
三、内存溢出
当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误。
for (let index = 0; index < 10000000000; index++) {
let element = new Array(10000000)
}
四、常见的js内存泄露
1.全局变量
在js中,一个未声明变量的使用,会在全局对象中创建一个新的变量;在浏览器环境下,全局对象就是window
function test() {
names = 'hsq'
}
test();
console.log(names);//hsq
相当于
function test() {
window.names = 'hsq'
}
test();
console.log(window.names);//hsq
解决办法:
①使用js严格模式
未声明但直接赋值的变量将失败
//js文件
"use strict";
function test() {
names = 'hsq'
}
test();
console.log(names);//报错
②变量使用完后将变量的内存释放
function test() {
names = 'hsq'
}
test();
console.log(names);//hsq
names = null
console.log(names);//null