关于js的垃圾收集机制

什么是垃圾

一般来说,没有被引用或访问不到的对象就是垃圾。

垃圾收集机制的原理

JavaScript具有自动垃圾回收机制,其原理是:找出不再继续使用的变量,然后释放其内存。这一操作会按照固定的时间间隔(或代码执行中预定的收集时间)周期性执行。而对于如何找出不再继续使用的变量,有标记清除法和引用计数法两种方法。一旦辨别完毕,这些内存区域即可在未来的分配中重用,或者是返还给操作系统。

标记清除法(主流方法)

介绍

这个算法把“对象是否不再需要”简化定义为“对象是否可以获得”。
当变量进入环境(比如在函数中声明一个变量)时,将该变量标记为”进入环境“。当变量离开环境时,将其标记为”离开环境“。最后,垃圾收集器完成内存清除的工作,销毁那些带标记的值并回收他们占用的内存空间。
至于如何标记变量,可以通过翻转某个特殊的位,也可以用两个列表分别存储进入环境的变量和离开环境的变量等。

一些优化

分代回收
对象分为两组:“新对象”和“旧对象”。许多对象出现,完成它们的工作并迅速结束,它们很快就会被清理干净。那些活得足够久的对象,会变“老”,并且很少接受检查。

增量回收
如果有很多对象,并且我们试图一次遍历并标记整个对象集,那么可能会花费一些时间,并在执行中会有一定的延迟。因此,引擎试图将垃圾回收分解为多个部分。然后,各个部分分别执行。这需要额外的标记来跟踪变化,这样有很多微小的延迟,而不是很大的延迟。

空闲时间收集
垃圾回收器只在 CPU 空闲时运行,以减少对执行的可能影响。

限制

那些无法从根对象查询到的对象都将被清除。

引用计数法

此算法把“对象是否不再需要”简化定义为“对象有没有其他对象引用到它”。
如果没有引用指向该对象(零引用),对象将被垃圾回收机制回收。 当声明了一个变量并将一个引用类型的值赋给该变量时,该值的引用次数为1。接着,如果该值又被赋给另一个变量,引用次数+1。如果包含该值引用的变量被赋予了另一个值,引用次数-1。

var a = {m: 1}; // 对象 `{t: 1}` (以下简称obj)被引用一次
var b = a; // obj 被引用两次
a = null; // obj 现在为1次
b = null; // obj 现在为0次,可回收

限制(循环引用)

循环引用时,两个对象都至少被引用了一次,将不能自动被回收。所以导致内存泄露。
如下面的例子所示:

function(){
	var a = {m: 1}; // 对象 `{m: 1}` (以下简称obj1)被引用一次
	var b = {n: 2}; // 对象 `{m: 1}` (以下简称obj2)被引用一次
	a.m = b;	// obj1被引用两次
	b.n = a;	// obj2被引用两次
}

当函数执行完毕后,由于obj1和obj2的引用次数都为2,这两个对象将依然存在而不会被回收。
IE9之前的版本中DOM和BOM对象存在这种问题。

管理内存

为了防止运行JavaScript的网页耗尽全部系统内存而导致系统崩溃,分配给Web浏览器的可用内存数量通常比分配给桌面应用程序的少很多。内存限制问题不仅会影响给变量分配内存,同时还会影响调用栈以及在一个线程中能同时执行的语句数量。
因此,确保占用最少的内存可以让页面获得更好的性能。优化内存占用的最佳方式,就是为执行中的代码只保存必要的数据。一旦数据不再有用,最好通过将其设置为null来释放引用。

编写代码建议

对于大多数全局变量和全局对象,当不再使用时手动置null,解除引用。
注意:解除一个值的引用并不意味着自动回收该值所占用的内存。解除引用真正的作用是让值脱离执行环境,以便垃圾收集器下次 运行时将其回收。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值