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垃圾收集机制和内存管理的全部内容,希望能对大家有所帮助。