浅谈JavaScript垃圾收集——标记清除和引⽤计数
JavaScript具有⾃动垃圾收集机制,执⾏环境会负责管理代码执⾏过程中使⽤的内存。也就是说,所需内存的分配和⽆⽤内存的回收完全实现了⾃动管理。
垃圾回收机制的原理:垃圾收集器会按照固定的时间间隔或代码执⾏中预定的收集时间,周期性地执⾏以下操作——出不再继续使⽤的变量,然后释放其占⽤的内存。
⽤于标识⽆⽤变量的⽅式有两种:标记清除法和引⽤计数法。
怎样删除ie1、标记清除法:
JavaScript最常⽤的垃圾收集⽅式。当变量进⼊环境时,这个变量标记为“进⼊环境”;⽽当变量离开环境时,则将其标记为“离开环境”。可以使⽤⼀个“进⼊环境”的变量列表及⼀个“离开环境”的变量列表来跟踪变量的变化,也可以翻转某个特殊的位来记录⼀个变量何时进⼊环境及离开环境。
2、引⽤计数法:
不太常见的垃圾收集策略。引⽤计数的含义是跟踪记录每个值被引⽤的次数。当声明了⼀个变量并将⼀个引⽤类型值赋给该变量时,则该值的引⽤次数就是1;如果同⼀个值⼜被赋给另⼀个变量,则该值的引
⽤次数加1;如果包含对该值引⽤的变量⼜取得了另外⼀个值,则该值的引⽤次数减1。当该值的引⽤次数变为0时,则可以回收其占⽤的内存空间。当垃圾回收器下⼀次运⾏时,就会释放那些引⽤次数为0的值所占⽤的内存。
问题:循环引⽤。
对象A包含⼀个指向对象B的指针,⽽对象B中也包含⼀个指向A的指针。
function obj() {
var objA = new Object();
var objB = new Object();
objA.propertyA = objB;
objB.propertyA = objA;
}
objA和objB的引⽤次数都是2,采⽤标记清除策略时,函数执⾏后,两个对象都离开了作⽤域,因此相
互引⽤不是问题,但采⽤引⽤计数策略时,函数执⾏后,两个对象还将继续存在,因为它们的引⽤次数永远不会为0。
因此⼀般不推荐⽤引⽤计数法,推荐使⽤标记清除法。
然⽽,IE中有⼀部分对象并不是原⽣JavaScript对象,如BOM和DOM对象就是使⽤C++以COM(组件对象模型)对象的形式实现的,⽽COM对象的垃圾收集机制采⽤的就是引⽤计数策略,因此,即使IE的JavaScript引擎是使⽤标记清除策略实现的,但JavaScript访问的COM对象依然是基于引⽤计数策略的,也即是说,只要IE中涉及COM对象,就会存在循环引⽤的问题。
var element = ElementById("element");
var obj = new Object();
obj.property1 = element;
element.property2 = obj;
解决:⼿动断开两个对象之间的相互引⽤。
在使⽤完毕后,⼿动断开原⽣JavaScript对象与DOM元素之间的连接,消除循环引⽤。当垃圾回收器下⼀次运⾏时,就会会删除这些值并回收它们占⽤的内存。
obj.property1 = null;
element.property2 = null;
解除引⽤:
⼀旦数据不再有⽤,最好通过将其设置为null来释放其引⽤。
然⽽,解除⼀个值的引⽤不意味着⾃动回收该值所占⽤的内存,解除引⽤的真正作⽤是让值脱离执⾏环境,以便垃圾收集器下次运⾏时将其回收。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论