JS内存泄漏与垃圾回收机制
文章类型:Javascript
发布者:admin
发布时间:2023-02-23
一原理:
1:内存泄漏:
a:是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果
b:通俗来说,就是程序的运行需要内存,对于持续运行的服务进程,必须及时释放内存,否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃,如果对于没有用到的内存,没有及时释放,归还给操作系统,就会导致内存泄漏
2:垃圾:一般来说没有被引用的对象就是垃圾,就是要被清除,有个例外如果几个对象引用形成一个环,互相引用,但根访问不到它们,这几个对象也是垃圾,也要被清除。
3:溢出:程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
3:js垃圾回收机制原理:解决内存的泄露,垃圾回收机制会定期(周期性)找出那些不再用到的内存(变量),然后释放其内存。
4:垃圾回收的必要性:因为没有大小限制,只有创建时候动态分配,如果不及时释放,会导致内存升高,系统崩溃情况
5:方式
a:标记清除:变量进入执行环境是,就标记这个变量为“进入环境”,当离开环境时,则将其标记为“离开环境”,则释放内存
b:引用计数:引擎有一张”引用表”,保存了内存里面所有资源(通常是各种值)的引用次数。如果一个值的引用次数是0,那么久该被释放
二:举例
1:
var a = "hi";
var b = "tom";
var a = b; //重写a
代码运行之后,“hi”这个字符串失去了引用(之前是被a引用),系统检测到就会释放该字符串的存储空间以便这些空间可以被再利用。
2:
const arr = [1,2,3];
console.log("hello world");
上面的代码中,数组[1,2,3]是一个值,会占用内存。变量arr是仅有的对这个值的引用,因此引用次数为1。尽管后面的代码没有用到arr,它是会持续占用内存
let arr = [1,2,3,4];
console.log("hello world");
arr = null;
如果针对arr进行一个赋值为null操作,那么引用次数为0,则释放内存
3:
function problem() {
var objA = new Object();
var objB = new Object();
objA.name= objB;
objB.age= objA;
}
objA和objB通过各自的属性相互引用;也就是说这两个对象的引用次数都是2。在采用引用计数的策略中,由于函数执行之后,这两个对象都离开了作用域,函数执行完成之后,objA和objB继续存在,引用次数不是0。相互引用导致内存泄露
如果存在循环引用的情况,那么这个引用值占的空间就永远不会被回收。,只有手动切断他们的循环引用。
objA.name = null;
objB.age =null;
三:常见的内存泄漏
1:意外的全局变量,未申明变量的使用,导致指向全局window,挂载在上面,不能被清理
2:计时器和回调函数timers ,在没有使用的时候,没有clear,导致不能被回收
3:DOM泄漏,主要是集中在事件、引用没被清理
4:js闭包,本身不会导致,主要是使用不当导致环形引用,可能导致内存泄漏
5:console,打印的数据不能及时清除,保存在内存中,不能被回收
四:怎么避免内存泄漏
a:减少不必要的全局变量,采用严格模式
b:逻辑优化,避免死循环
c:避免创建过多的对象,不用记得赋值为null