什么是垃圾回收?
在说这个东西之前,先要解释什么是内存泄漏,因为内存泄漏了,所以引擎才会去回收这些没有用的变量,这一过程就叫垃圾回收
什么是内存泄漏?
程序的运行需要占用内存,当这些程序没有用到时,还不释放内存,就会引起内存泄漏。举个通俗的例子,就好比占着茅坑不拉屎,坑位(内存量)就这么多,你还不出去(释放内存),就会引起想拉的人不能拉(系统变卡,严重点的会引起进程崩溃)
也就是说不再用到的内存,没有及时释放,就被称为内存泄漏。而内存泄漏,会让系统占用极高的内存,让系统变卡甚至奔溃。所以会有垃圾回收机制来帮助我们回收用不到的内存
当我们遇到遇到内存泄漏时,我们需要做什么呢?
不需要做任何事,因为 JavaScript 中的垃圾回收是自动的
JavaScript中的垃圾回收机制是基于标记清除算法实现的,该算法的核心思想是通过标记不再需要使用的对象,并将其删除。具体实现步骤如下:
一、标记阶段:首先,垃圾回收器会从根对象开始遍历所有能够访问到的对象,并将其打上标记。
在标记-清除算法的基础上,还有一些优化技术用于提高垃圾回收的效率:
-
分代回收(Generational Collection):根据对象的存活时间将堆分为不同的代(Generation),一般分为新生代(Young Generation)和老生代(Old Generation)。大部分对象都是临时创建的,而只有少部分对象长时间存活。通过针对不同代采取不同的回收策略,可以提高垃圾回收的效率。
-
增量回收(Incremental Collection):将整个垃圾回收过程分解为多个小步骤,与代码执行交替进行。这样可以避免长时间的停顿,减少对代码执行性能的影响。
二、空闲时回收(Idle-time Collection):在浏览器空闲时进行垃圾回收,利用空闲时间来清理不再使用的对象。这种方式可以减少对用户交互的干扰尔垃圾清除阶段:然后,垃圾回收器会删除所有没有标记的对象,并将其内存释放出来。这些被删除的对象就成为了垃圾。
除了"标记-清除"算法之外,JavaScript还有其他几种常见的垃圾回收机制。以下是其中两种:
-
引用计数(Reference Counting):该机制通过跟踪每个对象被引用的次数来进行垃圾回收。当一个对象被引用时,它的引用计数加一;当一个对象的引用失效时,它的引用计数减一。当引用计数为零时,表示该对象不再被引用,可以被释放。然而,引用计数机制可能存在循环引用的问题,即两个或多个对象相互引用导致它们的引用计数始终不为零,无法被回收。
-
分代回收(Generational Collection):在分代回收机制中,堆被划分为不同的代,一般分为新生代和老生代,每个代采用不同的回收策略。新生代中的对象通常存活时间较短,因此采用较轻量级的回收算法,如复制算法或标记-整理算法。老生代中的对象通常存活时间较长,采用更耗时但更全面的标记-清除算法或标记-整理算法。通过分代回收,可以根据对象的存活时间来优化垃圾回收的效率。
JavaScript的垃圾回收机制是自动进行的,即由JavaScript引擎自动管理内存。开发者并不需要手动管理内存,但需要注意一些影响垃圾回收机制效率的因素,如循环引用、大量全局变量等。建议在开发过程中尽量减少这些因素的影响,以提高程序的性能与稳定性。