垃圾回收机制

郭浪 Lv3

首先我们要先了解一下为什么需要使用垃圾回收机制,在js中我们使用的所有变量都会在内存中开辟一个新的空间来存储数据,数据在解析完成之后需要释放掉占用的内存,在chrome的v8引擎中引入了自动释放内存的机制就是垃圾回收机制。

一般的垃圾回收机制的方案

引用计数

在解析过程中我们每个对象的使用我们都会增加一次引用次数,后面如果给对象赋值了一个不需要内存空间的空值的话这个引用次数就会减一,什么时候这个对象的引用次数变成 0 了就会被垃圾回收器释放掉(形成了一个孤岛对象)

1
2
3
4
5
6
7
8
//这里我们把对象o引用给了obj1这个变量
var obj1 = { age: 18 }; // +1
var obj2 = obj1;// +1

obj1 = null; //这里o的引用次数减少一次 -1
obj2 = null; //这里o的引用次数又减少一次 -1

//这个时候o的引用次数变成0了触发垃圾回收机制 内存被垃圾回收机制回收

引用计数的弊端是解决不了循环引用的问题

1
2
3
4
5
6
7
8
9
var obj1 = { age: 18 }; // 这里对象01的引用次数+1
var obj2 = { liek: codeing }; //这里对象02的引用次数+1

obj1.xxx = obj2; //对象02的引用次数+1
obj2.xxx = obj1; //对象01的引用次数+1

obj1 = null; //对象01 -1
obj2 = null; //对象02 -1
//这个时候两个对象形成了循环引用展开的层数是无限的 使用引用计数的话就不会把两个对象清除因为对象一致处于引用状态(变成了不可达对象但是对象中存在相互引用次数还不为0所以不会释放内存)

标记清除

  1. 首先会把所有的变量都加上标记
  2. 把所有可达的变量的标记都清除(可达:就是可以通过某种方式访问到的变量)
  3. 剩下的所有带标记的变量都是孤岛变量在程序中不需要使用可以被清除
  4. 开始清除所有带标记的变量

在开发的时候那些行为会导致出现内存泄露

内存泄露就是这个对象没有被引用的但是内存还没有被释放

  1. 意外的全局变量 比如有时候声明变量的时候没有在前面添加let、const、var这样声明的变量会被解析成一个全局的变量,全局的变量是不会被垃圾回收的
  2. 闭包的行为,闭包会造成内存浪费
  3. DOM的引用,在声明一个DOM的事件的时候我们要绑定一个回调函数实际上是把这个函数方法添加到DOM对象中的属性上这里我们删除DOM对象中的事件的时候对这个函数的引用其实还是在的,这个时候我们要想把函数的内存给清除掉的话就要手动的把DOM对象给清除掉
  • 标题: 垃圾回收机制
  • 作者: 郭浪
  • 创建于: 2023-06-14 19:33:08
  • 更新于: 2023-08-14 20:42:44
  • 链接: https://redefine.ohevan.com/2023/06/14/垃圾回收机制/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。