学习Javascript的垃圾收集机制和内存管理

学习Javascript的垃圾收集机制和内存管理
1。垃圾收集机制

Javascript具有自动垃圾回收机制(GC:垃圾配套),即执行环境负责管理用于执行的代码的内存

原理:垃圾收集器将周期性地(周期性地)找出不使用的变量,然后释放它们的内存。

Javascript垃圾收集的机制很简单:找出不再使用的变量,然后释放占用的内存,但是这个过程不是实时的,因为成本很大,所以垃圾收集器将在固定的时间间隔周期性地执行。

不再使用的变量是结束生命周期的变量。当然,这只能是一个局部变量和全局变量的生命周期将在网页浏览卸载完成。局部变量只在函数的执行过程中,在这个过程中,对相应空间的局部变量分配在栈或堆存储值,然后使用这些变量的函数,直到关闭功能的结束,因为内部函数和外部函数不是结束。

或代码描述:
功能FN1(){
var obj = {姓名:'hanzichi,年龄:10 };
}

功能Fn2(){
var obj = {姓名:'hanzichi,年龄:10 };
返回对象;
}

var a = FN1();
var b = FN2();

让我们来看看如何执行该代码。我们定义了两个函数,命名为FN1和FN2,当FN1称,在FN1环境,将开辟一个存储对象{姓名:'hanzichi,年龄:10 },和呼叫结束时,FN1环境,所以内存块将在垃圾回收器自动释放FN2调用JS引擎;在这个过程中,返回的对象是全局变量B点,所以内存块并不会发布。

这里出现的问题是:哪个变量是没有用的因此,垃圾收集器跟踪哪些变量是无用的,标记不再有用,在未来恢复变量存储器。标记无用的变量的策略可能会从不同的实现,通常有两种实现方式:马克清除和引用计数。引用计数是不经常使用,和显著的清除比较常用的是。

二、显著清除

在JS最常用的垃圾收集是明显的间隙。当一个变量进入环境,例如,声明一个变量在一个函数中,变量是标记为入口环境。从逻辑上讲,我们不能释放进入环境的变量占用的内存,因为我们可以用它们只要执行流进入相应的环境。当变叶的环境中,它被标记为离开环境。
函数测试(){
var a = 10; /标记,进入环境
var b = 20; /标记,进入环境
}
(测试);在A之后执行,B也要离开环境,循环使用。

垃圾回收器将所有的变量存储在内存运行时(当然,也可以用任何方式)。然后,它会去除环境中的和标记的变量(Bi Bao),是由环境中的变量引用。之后,对标签添加变量将被视为一个变量可以被删除,因为在环境变量已经无法访问这些变量。最后,垃圾收集器完成记忆清除,摧毁那些标记值和内存空间,他们占据回收。

到目前为止,JS、Firefox、Opera、Chrome和Safari的js实现都采用了垃圾收集策略或类似策略,但垃圾收集的时间间隔是不同的。

三。引用计数

引用计数的意义是跟踪次数每个价值参考。当一个变量被声明和引用类型的值赋给变量,对价值的参考人数是1。如果同一个值是给另一个变量的值,参考人数增加1。相反,如果包含引用的值的变量有另一个值,该值的引用的数量减少了1。当数这个值变成0篇,这说明没有办法再访问的价值,使内存空间占用可以返回。这样,当垃圾收集器运行一次,它释放的价值0的Num占用的内存参考文献。
函数测试(){
var;引用数为0
var a = a;引用的次数为1加1。
var = a;引用到2加1的数目是
var;{引用;引用/减号a减去1, 1
}
Netscape navigator3是使用引用计数策略的第一个浏览器,但它很快就来到了一个严重的问题:循环引用。循环引用意味着一个对象包含一个指向对象B,和B的对象还包含一个对象的引用:

函数FN(){
var = { };
var;
a.pro = B;
b.pro =一;
}

(FN);
上面的代码引用的A和B的号码是2,(FN)的执行完成后,两个物体离开环境,在马克扫描模式是没有问题的,但在引用计数的策略,因为A和B的引用数不为0,那么它将没有如果FN功能被垃圾收集器回收内存,通过大量调用,会导致内存泄漏,在IE7和IE8,记忆在直线上升。

我们知道,在IE中的一些对象不是原生js对象。例如,它的内存泄漏,在DOM和BOM对象是使用C++ COM对象的形式实现的,而COM对象的垃圾收集机制采用引用计数策略。因此,即使IE的JS引擎一个标记清晰的战略实施,COM对象,JS访问仍然是基于引用计数的策略。换句话说,只要COM对象是参与伊江,会有一个循环引用的问题。
VaR元= document.getelementbyid(some_element );
VaR MyObject =新的对象();
MyObject E =元;
O = MyObject的元素;
此示例创建一个DOM元素之间的循环引用(元)和本地JS对象(MyObject)。在这方面,有一个属性变量MyObject命名元素指向该元素的对象;和可变元素有一个属性叫做O照应MyObject。由于这种循环引用,即使在例如DOM被删除的网页,它将不会被回收。

看看上面的例子,有些学生认为它太弱了,谁会做这么无聊的事情,其实,我们不是在做它。
窗口。指针函数outerfunction(){
var obj = document.getelementbyid(元);
obj。onclick=功能(innerfunction){ };
};
这个代码似乎不是一个问题,但目标是指document.getelementbyid(元),而document.getelementbyid(元)的onClick方法指的是在外部环境变量的德国,自然包括obj,太。

和解条款

最简单的方法是手动删除循环引用,例如您刚才拥有的函数。
myobject.element = null;
元素;
窗口。指针函数outerfunction(){
var obj = document.getelementbyid(元);
obj。onclick=功能(innerfunction){ };
obj = null;
};
将变量设置为NULL意味着切断变量和它先前引用的值之间的连接。当垃圾收集器下次运行时,这些值将被删除,它们的内存被占用。

需要注意的是,IE9 +没有循环引用导致DOM内存泄漏的重要,也许微软做了优化,或Dom已开垦的方式已经发生了变化。

四。内存管理

1。何时会触发垃圾回收

如果垃圾收集器周期性地运行,如果分配的内存非常大,那么恢复将非常困难。垃圾收集间隔的确定是一个值得探讨的问题pondering.ie6垃圾收集是根据运行的内存分配量,垃圾回收器将触发工作时有256个任意的字符串变量,4096个对象在64K的环境情况,看起来很科学,不是通过一段时间,称为一次,有时是不必要的这样的要求,不要求很好吗但是如果环境存在这么多变量,那么脚本是如此复杂,非常正常,结果垃圾收集器一直在工作,因此浏览器不能播放。

微软的IE7调整,触发条件是不固定的,而是动态变化的,初始值和相同的IE6,如果垃圾收集器的内存分配是小于15%的程序存储器,大部分的记忆不能回收,回收的触发条件过于敏感,这个时候街上的条件双,如果内存的回收率大于85%,表明大部分的记忆都清理了,这一次的触发条件设置回来。这使得许多垃圾收集工作

2。合理的GC方案

1),Javascript引擎基础GC方案是(简单GC):标记和扫描(有标记的清除),即:

(1)遍历所有可访问对象。
(2)回收整理的对象。
2)气相色谱法的缺陷

与其他语言,Javascript的GC策略无法回避的问题:当GC,停止响应其他操作,这是出于安全的考虑,Javascript的GC更好在100ms和一般应用的比较多,但对于JS的游戏,它是动画需要更多的连贯性在应用这麻烦。是的,新的发动机需要优化:避免长时间停止响应的GC引起的。

3),GC优化策略

戴维叔叔主要介绍了2种优化方法,这是2种最重要的优化方法。

(1)生成恢复(生成GC)

这是用java回收策略观点一致,目的是区分暂时性和持久性对象,收集更多的年轻一代,并恢复终身终身,减少时间来遍历每个对象,从而减少了每个GC的时间。图:
在这里,我们需要补充的是,对于年老代对象,有额外的成本:迁移从年轻一代的终身代,此外,如果引用,参考点也需要修改

(2)增量GC

这个方案的思想非常简单,即一次处理一个点,下一次处理一个点,等等:
该方案虽然耗时,但存在大量的中断,带来频繁上下文切换的问题。

由于每个方案都有其应用场景和缺点,所以在实际应用中,将根据实际情况选择方案。

例如,当中断低(对象/ s)比率时,GC执行的频率较低,简单GC较低。如果大量的对象是长寿命的,那么生成处理的优势就不大了。

参考资源uff1a

以上是关于javascript垃圾收集机制和内存管理的全部内容,希望能对大家有所帮助。
免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部