JavaScript垃圾收集
最后更新于:2022-04-01 11:43:53
JS具体自动垃圾收集机制(Java也有GC);也就是说,执行环境会负责管理代码执行过程中使用的内存。在编写JS程序时,开发人员不用再关心内存使用问题,所需内存的分配以及无用内存的回收完全实现了自动管理。这种垃圾收集器会按照固定的时间间隔(或代码中预定的收集时间),周期性的执行这一操作;
下面让我们一起来分析一下函数中局部变量的正常生命周期。局部变量只在函数执行的过程中存在,而在这个过程中,会为局部变量分配相应的内存空间,以便存储它们的值。然后在函数中使用这些变量,直至函数执行结束。此时局部变量就没有存在的必要了,因此可以释放内存以供将来使用。对于垃圾Js垃圾收集来说一般也就是两种策略,这两种策略感觉和Java很相似;
**标记清除:**
JS中最常用的垃圾收集方式是标记清楚(mark-and-swecp)。当变量进入环境时,我们会标记为“进入环境,并且给它一个标示。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要进入到了相应的环境,那么我们的浏览器就有可能用到它们,而当变量离开环境时。则将其标记为离开环境;
可以在使用任何方式来标记变量。比如,可以通过翻转某个特殊的位来记录一个变量何时进入环境,或者使用一个进入环境的变量列表及一个离开环境的变量列表来跟踪哪个变量发生了变化。说到底,如何标记变量其实并不重要,关键在于采取什么策略。
垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记,然后,它会去掉环境中的变量及被环境中的变量引用的变量的标记。而在此之后再被加上离开环境时标记的变量讲被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了,最后,垃圾收集器完成内存的清除工作。销毁哪些带标记的值,并回收他们所占用的内存空间。
**引用计数:**
另一种不太常见的垃圾收集策略叫做引用计数(Reference counting)。引用计数的含义是跟踪记录每个值被引用的次数。当一个变量引用了另一个变量的时候,则这个值就会加1,如果一个变量又赋值给了另外一个变量,则再加1.相反如果又没有引用这个值的变量了,那么会减1.当这个值的引用次数为0时,则说明没有办法在访问这个值了,因而可以将其占用的内存空间回收回来。这样,当垃圾收集器下次再执行时,它就会释放那些引用次数为零的值所占用的内存。
但是这样有一个很严重的Bug,就是循环引用。即A对象中包含一个指向对象B的指针,而对象B中也包含一个指向对象A的引用。
~~~
function problem(){
var objectA=new Object();
var objectB=new Object();
objectA.aobject=objectB;
objectB.bobject=objectA;
}
~~~
在上面的这个例子中,两个对象的属性相互引用;也就是说。这两个对象的引用次数都是2.在采用标记清除策略的实现中,当函数执行完毕后,两个变量还继续存在,因为它们的引用次数永远都不会是0.假如这个函数被重复多次调用,就会导致大量内存得不到回收。为此现在用的最多的就是标记清除。可是引用计数导致的麻烦还未就此终结;
**性能问题:**
垃圾收集器是周期性运行的,而且如果为变量分配的内存数量很客观,那么回收工作量也是相当大的,在这种情况下,确定垃圾收集的时间间隔是一个非常重要的问题。说到垃圾收集器多长时间运行一次,IE的垃圾收集器是根据内存分配量运行的,具体一点说就是256个变量,4096个对象或数组字面量和数组元素(slot)或者64KB的字符串,达到上述任何一个临界值,垃圾收集器就会运行。这种实现方式的问题在于,如果一个脚本中包含那么多变量,那么该脚本很可能会在生命周期
中一直保存着那么多变量,而这样一来,垃圾收集器就不得不频繁的运行。后来IE7就重写了其垃圾收集例程。
管理内存:
使用具备垃圾收集机制的语言编写程序,开发人员一般不必担心内存管理的问题,但是Js在进行内存管理和垃圾收集时面临的问题还是于众不同。最主要的就是分配给微博web浏览器的内存数量要比桌面应用程序少。这样是出于安全方面考虑,内存限制问题不仅会影响给变量分配内存,同时还是影响调用栈以及一个线程中能够同时执行的语句数量。
因为优化内存占用是一个好习惯,一旦数据不再用,最好设置为null,来释放其引用,这个做法叫做接触引用。
**GC优化策略:**
(1)分代回收(Generation GC)
这个和Java回收策略思想是一致的。目的是通过区分“临时”与“持久”对象;多回收“临时对象”区(young generation),少回收“持久对象”区(tenured generation),减少每次需遍历的对象,从而减少每次GC的耗时。
(2)增量GC
这个方案的思想很简单,就是“每次处理一点,下次再处理一点,如此类推”