js 垃圾回收机制

垃圾回收是编程语言必不可少的环节,当一个变量被定义时,会在系统中分配一个内存来储存变量的值,而当这个变量不在使用的时候就需要对变量进行回收,释放内存。

如果垃圾不进行回收就会照成内存泄露的情况,内存泄露可能会导致卡顿或者崩溃。

在编程语言中,c 语言需要手动对垃圾进行回收,而java 和 javascript 系统会自动进行垃圾回收。

javascript 中的垃圾回收机制有两种:

一、引用计数

  引用计数回收机制是通过对一个值的引用次数进行统计,当这个值被付给一个变量时会给这个值标记为引用一次,如果这个值在被付给另外一个变量,则会给这个变量标记为引用两次。当这个值的引用次数为0时,下次垃圾回收时会把这个值进行回收。

  但是引用计数垃圾回收机制有个问题,就是循环引用,导致垃圾不能被回收。

1 function problem () {
2    var objectA = new Object();
3    var objectB = new Object();
4 
5    objectA.someOtherObject = objectB;
6    objectB.anotherObject = objectA;       
7 }
8 
9 problem();

上面为《JavaScript 高级程序设计》中的一个例子。

当执行problem 函数时创建一个objectA 变量指向一个空的Object、创建一个objectB 变量执行一个空的Object。

并将objectB 的引用赋值给objectA的someOtherObject 属性,将objectA 的引用赋值给objectB的anotherObject 属性。此时两个空对象的引用数量都为2(空对象为new Object() 在赋值给objectA 时引用计数加1,在赋值给objectB.anotherObject 时加1,所以此时objectA 所指向的空对象的引用为2,objectB 指向的空对象引用次数同理)

因此在函数执行结束后objectA 和 objectB 所指向的空对象都不能被回收,如果多次执行problem函数会导致内存中有大量的对象无法被清除。

所以此垃圾回收机制被浏览器淘汰,各浏览器选择了使用另外一个垃圾回收机制进行垃圾回收--标记清除

 

二、标记清除

  标记清除是通过变量进入环境(即在执行预编译的时候将变量放入到作用域中)时对变量进行标记(标记为进入进入),当变量离开环境时又会被标记为离开环境。当垃圾回收时会将内存中的所有变量标记为可回收,然后再将环境中的变量和被环境中变量引用的变量的标记清除,然后对被标记的变量进行销毁和回收。

posted @ 2020-03-04 20:55  小小_先森  阅读(...)  评论(...编辑  收藏