js垃圾回收机制详解

简介

  • 一、前言
  • 二、什么是内存泄漏
    • 1. 引用计数
    • 2. 标记清除
  • 三、总结

一、前言

大家好,我是思航。最近我们游戏在进行内存优化,所以大家网上找了很多教程,来定位和查找内存泄漏问题。今天呢,我打算换个角度来聊聊这个问题。

二、什么是内存泄漏

当计算机动态内存不再需要时,应该释放。如果没有释放,就会产生内存泄漏。
即:当我们认为不需要了,但是js却没有回收时,就产生了内存泄漏

我们认为不需要了 ==> 对象清空、关闭界面等操作

js 认为内存不需要了 ==> 需要了解 js的 垃圾回收机制

1. 引用计数

我们通过下面一个例子来讲一下引用计数的机制。

function func () {
	var objA = {a: 1};
	var objB = objA;
	objA = null;
	objB = null;
}

js垃圾回收机制详解_第1张图片
通过上面图解,我们可以看到,当函数 func执行后,对象{a:1}所占用的内存因为没人引用了,就会被释放掉。

在早期使用引用计数的时候,很容易因为循环引用问题,导致内存泄漏。下面我们还是通过一个例子来看下。

function func () {
	var objA = {};
	var objB = {};
	objA.a = objB; // 这边两个对象互相引用
	objB.a = objA;  
	objA = null;
	objB = null;
}

js垃圾回收机制详解_第2张图片
通过上面图解可以看到,当函数执行完后,两个对象还互相引用着,所以不会被释放,导致了内存泄漏。

当然我们可以通过手动解开引用,来处理这个问题。

function func () {
	var objA = {};
	var objB = {};
	objA.a = objB;
	objB.a = objA;
	objA.a = null; // 这边解开引用
	objB.a = null;
	objA = null;
	objB = null;
}

2. 标记清除

现在浏览器基本都使用了标记清除垃圾回收方式。
js中的全局对象,在浏览器中是window对象。定期的从这个全局对象开始,递归查找引用的对象,如果能访问到,就表示活着,不会被释放。

还是之前的例子:

function func () {
	var objA = {};
	var objB = {};
	objA.a = objB; // 这边两个对象互相引用
	objB.a = objA;  
	objA = null;
	objB = null;
}

js垃圾回收机制详解_第3张图片
虽然最后两个对象互相引用着,但是这两个对象并不能通过window对象访问到,所以会被回收掉。

三、总结

通过上面我们了解了js的垃圾回收机制(现在主流使用的是 标记清除
只有知道了原理,我们才能够更好地避免写出有问题的代码。而不是通过查了一些教程,就开始使用控制面板里面的 Performance( 更多是用来查性能问题) 和 Memory (查找内存问题) ,而我更希望是大家在知道了什么是内存泄漏后,再去学习怎么定位内存泄漏。

你可能感兴趣的:(javascript,前端)