垃圾回收机制
- 垃圾回收GC的全拼是 Garbage Collection
- 其在维基百科的定义是: 在计算机科学中,垃圾回收(英语:Garbage Collection,缩写为GC)是一种自动的内存管理机制。
- 当一个电脑上的动态内存不再需要时,就应该予以释放,以让出内存,这种内存资源管理,称为垃圾回收(garbage collection)
- 有些语言(比如 C 语言)必须手动释放内存,程序员负责内存管理。
char * buffer;
buffer = (char*) malloc(42);
free(buffer);
- 这很麻烦,所以大多数语言提供
自动内存管理 ,减轻程序员的负担,这被称为"垃圾回收机制"(garbage collector) - 垃圾回收机制怎么知道,哪些内存不再需要呢?这就要牵涉到一些垃圾回收算法了
- 常见的垃圾回收算法:
1. 引用计数算法
2. 标记清除算法
3. 标记压缩算法
4. 待续。。。。
1. 吞吐量 throughput
2. 最大暂停时间
3. 堆使用效率
4. 访问的局部性
引用计数算法
- 这是最初级的垃圾收集算法。
- 此算法把“
对象是否不再需要 ”简化定义为“对象有没有其他对象引用到它 ”。 - 如果没有引用指向该对象(零引用),对象将被垃圾回收机制回收。
- 该算法有个限制:无法处理循环引用的事例。
- 示例:如果一个值不再需要了,引用数却不为0,垃圾回收机制无法释放这块内存,从而导致内存泄漏。
let arr = [1, 2, 3, 4];
console.log('hello world');
数组[1, 2, 3, 4]是一个值,会占用内存。
变量arr是仅有的对这个值的引用,因此引用次数为1。
尽管后面的代码没有用到arr,它还是会持续占用内存。
- 如果增加一行代码,解除arr对[1, 2, 3, 4]引用,这块内存就可以被垃圾回收机制释放了。
let arr = [1, 2, 3, 4];
console.log('hello world');
arr = null;
var o = {
a: {
b:2
}
};
var o2 = o;
o = 1;
var oa = o2.a;
o2 = "yo";
oa = null;
function f(){
var o = {};
var o2 = {};
o.a = o2;
o2.a = o;
return "azerty";
}
f();
例子中,两个对象被创建,并互相引用,形成了一个循环。
它们被调用之后会离开函数作用域,所以它们已经没有用了,可以被回收了。
然而,引用计数算法考虑到它们互相都有至少一次引用,所以它们不会被回收。
标记清除算法
- 从2012年起,所有现代浏览器都使用了标记清除垃圾回收算法。
- 所有对 JavaScript 垃圾回收算法的改进都是基于标记清除算法的改进。
- 并没有改进标记清除算法本身和它对“对象是否不再需要”的简化定义。
- 这个算法把“
对象是否不再需要 ”简化定义为“对象是否可以获得 ”。
1. 这个算法假定设置一个叫做根(root)的对象(在Javascript里,根是全局对象)。
2. 垃圾回收器将定期从根开始,找所有从根开始引用的对象,然后找这些对象引用的对象……从根开始,
3. 垃圾回收器将找到所有可以获得的对象和收集所有不能获得的对象。
4. 这个算法比引用计数算法要好,因为“有零引用的对象”总是不可获得的,但是相反却不一定
- 我们可以清楚地看到右边有一个“不可到达的块”。
- 现在让我们看看“标记并清除”垃圾回收器如何处理它。
- 垃圾回收器获取根并“标记”(记住)它们
- 然后标记他们的引用
- 以及子孙代的引用:
- 现在进程中不能访问的对象被认为是不可访问的,将被删除:
- 示例:循环引用不再是问题了
- 函数调用返回之后,两个对象从全局对象出发无法获取。
- 因此,他们将会被垃圾回收器回收
function f(){
var o = {};
var o2 = {};
o.a = o2;
o2.a = o;
return "azerty";
}
f();
尽管这是一个限制,但实践中我们很少会碰到类似的情况,所以开发者不太会去关心垃圾回收机制。
常见的改进和优化
1. 对象分为两组:“新对象”和“旧对象”。
2. 许多对象出现,完成它们的工作并迅速结 ,它们很快就会被清理干净。
3. 那些活得足够久的对象,会变“老”,并且很少接受检查。
1. 如果有很多对象,并且我们试图一次遍历并标记整个对象集,那么可能会花费一些时间,并在执行中会有一定的延迟。
2. 因此,引擎试图将垃圾回收分解为多个部分,然后,各个部分分别执行。
3. 这需要额外的标记来跟踪变化,这样有很多微小的延迟,而不是很大的延迟。
1. 垃圾回收器只在 CPU 空闲时运行,以减少对执行的可能影响。
|