详解JS——垃圾回收的原理

简介: 详解JS——垃圾回收的原理

引言

JavaScript是一种高级的、解释型的编程语言,广泛应用于网页开发和移动应用开发中。在JavaScript中,内存管理是一个重要的话题,而垃圾回收就是内存管理的一部分。本文将介绍JavaScript垃圾回收的原理,并提供一些示例代码来帮助理解。

什么是垃圾回收

JS 中的垃圾回收是一种自动化的过程,用于检测和释放不再使用的内存空间。在 JS 中,当我们创建变量、对象、函数等时,会在内存中分配一定的空间来存储它们。但是,当这些变量、对象、函数不再被使用时,它们占用的内存空间就变成了垃圾。

垃圾回收的目的是找出这些垃圾内存,并将其释放,以便其他部分可以使用它们。在 JS 中,垃圾回收器会自动扫描内存中的对象,标记那些仍然被使用的对象,并将未使用的对象标记为垃圾。然后,它会释放这些垃圾对象占用的内存空间。

JS 中的垃圾回收器通常使用“标记-清除”算法来实现。这种算法会先标记所有仍然被使用的对象,然后清除未被标记的对象。另外,JS 中的垃圾回收器还会使用“引用计数”算法来检测对象是否被引用,以及是否需要释放内存空间。

垃圾回收是 JS 中的一个重要特性,它可以避免内存泄漏和内存溢出等问题,提高程序的性能和稳定性。因此,在编写 JS 程序时,我们应该尽可能地避免创建不必要的变量、对象和函数,以减少垃圾回收的工作量。

垃圾回收的原理

JavaScript中的垃圾回收主要依靠垃圾收集器来实现。垃圾收集器会定期扫描内存,查找不再被引用的对象,并将其标记为垃圾。一旦对象被标记为垃圾,垃圾收集器就会释放它所占用的内存空间。

引用计数算法(Reference Counting)

  • 垃圾回收器会为每个对象维护一个引用计数器,记录当前对象被引用的次数。
  • 当一个对象被引用时,引用计数器加一;当一个对象的引用被释放时,引用计数器减一。
  • 当引用计数器为零时,表示该对象不再被引用,即为垃圾对象,垃圾回收器会立即回收并释放其占用的内存空间。

一种常见的垃圾回收算法是引用计数。在引用计数算法中,每个对象都有一个引用计数器,用于记录有多少个引用指向该对象。当引用计数器为0时,表示该对象不再被引用,可以被回收。

然而,引用计数算法存在一个问题,就是循环引用。如果两个对象相互引用,它们的引用计数器都不会变为0,即使它们已经不再被使用。这种情况下,垃圾收集器需要使用其他算法来解决循环引用的问题。

标记-清除算法(Mark and Sweep)

  • 垃圾回收器会从根对象开始,标记所有被根对象引用的对象为活动对象。
  • 然后,垃圾回收器会遍历所有的对象,标记被活动对象引用的对象为活动对象,依此类推,直到所有可达的对象都被标记为活动对象。
  • 最后,垃圾回收器会清除未被标记的对象,释放它们占用的内存空间。

标记-清除算法是另一种常见的垃圾回收算法。在标记-清除算法中,垃圾收集器首先会从根对象开始,遍历所有可访问的对象,并将它们标记为活动对象。然后,垃圾收集器会清除所有未被标记的对象,即垃圾对象。

标记-清除算法可以解决循环引用的问题,因为只有可访问的对象才会被标记为活动对象,不可访问的对象会被清除。

垃圾回收的原理总结

这两种算法在实际应用中常常结合使用。标记-清除算法用于检测和回收循环引用的对象,而引用计数算法用于快速回收不再被引用的对象。垃圾回收器会根据需要周期性地运行,自动进行垃圾回收,释放不再使用的内存空间。

需要注意的是,垃圾回收器并非实时回收垃圾,而是在特定的时机触发回收操作。这是因为垃圾回收过程会占用一定的计算资源,如果频繁触发垃圾回收,可能会导致程序性能下降。因此,垃圾回收的时机通常由浏览器或 JS 引擎决定,以平衡性能和内存占用。

示例代码

下面是一个简单的示例代码,演示了 JS 中的垃圾回收过程:

function createObject() {
  // 创建一个对象
  var obj = {};
  return obj;
}

function main() {
  // 创建一个对象
  var obj1 = createObject();

  // 创建另一个对象
  var obj2 = createObject();

  // 将 obj1 的引用赋值给 obj2
  obj2.ref = obj1;

  // 将 obj2 的引用赋值为 null,断开与 obj1 的引用
  obj2 = null;

  // 此时,obj1 仍然被 obj2.ref 引用,不会被回收
  // 如果将 obj1 的引用赋值为 null,那么 obj1 也会被回收
}

// 执行主函数
main();

在这个示例中,我们创建了两个对象 obj1obj2,并将 obj1 的引用赋值给 obj2。然后,我们将 obj2 的引用赋值为 null,断开了与 obj1 的引用。此时,obj1 仍然被 obj2.ref 引用,所以它不会被垃圾回收器回收。如果我们将 obj1 的引用也赋值为 null,那么 obj1 就没有任何引用了,它会成为垃圾对象,垃圾回收器会在适当的时机将其回收。

这个示例展示了垃圾回收的基本原理:当一个对象不再被引用时,它就成为垃圾对象,垃圾回收器会在适当的时机将其回收,释放内存空间。

结论

JavaScript 的垃圾回收机制是一项自动化的内存管理技术,它能够自动检测和回收不再使用的内存,以避免内存泄漏和内存溢出的问题。在 JavaScript 中,垃圾回收器会周期性地扫描内存,找出不再被引用的对象,并将其释放掉,以便其他对象可以使用这些空间。

垃圾回收的原理可以归纳为以下几点:

  1. 标记-清除算法:垃圾回收器会从根对象开始遍历内存中所有的对象,标记被引用的对象为活动对象,然后清除未被标记的对象,释放它们占用的内存空间。
  2. 引用计数算法:垃圾回收器会为每个对象维护一个引用计数器,记录当前对象被引用的次数。当一个对象的引用被释放时,引用计数器减一。当引用计数器为零时,表示该对象不再被引用,即为垃圾对象,垃圾回收器会立即回收并释放其占用的内存空间。

需要注意的是,垃圾回收器并非实时回收垃圾,而是在特定的时机触发回收操作。这是因为垃圾回收过程会占用一定的计算资源,如果频繁触发垃圾回收,可能会导致程序性能下降。因此,垃圾回收的时机通常由浏览器或 JS 引擎决定,以平衡性能和内存占用。

总之,垃圾回收是 JavaScript 中的一项重要的内存管理技术,它能够自动检测和回收不再使用的内存,以避免内存泄漏和内存溢出的问题。开发者可以通过了解垃圾回收的原理和机制,来优化程序的性能和内存占用。


目录
相关文章
|
7月前
|
Prometheus 监控 算法
CMS圣经:CMS垃圾回收器的原理、调优,多标+漏标+浮动垃圾 分析与 研究
本文介绍了CMS(Concurrent Mark-Sweep)垃圾回收器的工作原理、优缺点及常见问题,并通过具体案例分析了其优化策略。重点探讨了CMS的各个阶段,包括标记、并发清理和重标记
CMS圣经:CMS垃圾回收器的原理、调优,多标+漏标+浮动垃圾 分析与 研究
|
11月前
|
JavaScript 前端开发 算法
JS垃圾回收
【10月更文挑战第30天】JavaScript 的垃圾回收机制是保证程序稳定运行的重要组成部分。了解垃圾回收的原理和算法,以及注意避免内存泄漏的问题,可以帮助开发者更好地利用 JavaScript 进行高效的开发
|
4月前
|
机器学习/深度学习 JavaScript 前端开发
JS进阶教程:递归函数原理与篇例解析
通过对这些代码示例的学习,我们已经了解了递归的原理以及递归在JS中的应用方法。递归虽然有着理论升华,但弄清它的核心思想并不难。举个随手可见的例子,火影鸣人做的影分身,你看到的都是同一个鸣人,但他们的行为却能在全局产生影响,这不就是递归吗?雾里看花,透过其间你或许已经深入了递归的魅力之中。
165 19
|
7月前
|
存储 算法 Java
G1原理—5.G1垃圾回收过程之Mixed GC
本文介绍了G1的Mixed GC垃圾回收过程,包括并发标记算法详解、三色标记法如何解决错标漏标问题、SATB如何解决错标漏标问题、Mixed GC的过程、选择CollectSet的算法
G1原理—5.G1垃圾回收过程之Mixed GC
|
5月前
|
缓存 算法 Java
JVM深入原理(八)(一):垃圾回收
弱引用-作用:JVM中使用WeakReference对象来实现软引用,一般在ThreadLocal中,当进行垃圾回收时,被弱引用对象引用的对象就直接被回收.软引用-作用:JVM中使用SoftReference对象来实现软引用,一般在缓存中使用,当程序内存不足时,被引用的对象就会被回收.强引用-作用:可达性算法描述的根对象引用普通对象的引用,指的就是强引用,只要有这层关系存在,被引用的对象就会不被垃圾回收。引用计数法-缺点:如果两个对象循环引用,而又没有其他的对象来引用它们,这样就造成垃圾堆积。
152 0
|
5月前
|
算法 Java 对象存储
JVM深入原理(八)(二):垃圾回收
Java垃圾回收过程会通过单独的GC线程来完成,但是不管使用哪一种GC算法,都会有部分阶段需要停止所有的用户线程。这个过程被称之为StopTheWorld简称STW,如果STW时间过长则会影响用户的使用。一般来说,堆内存越大,最大STW就越长,想减少最大STW,就会减少吞吐量,不同的GC算法适用于不同的场景。分代回收算法将整个堆中的区域划分为新生代和老年代。--超过新生代大小的大对象会直接晋升到老年代。
106 0
|
6月前
|
JavaScript 前端开发 Java
js 垃圾回收机制的方法
JS回收机制方法讲解
|
7月前
|
存储 监控 架构师
ZGC圣经:ZGC垃圾回收器的原理、调优,ZGC 漏标的 分析与 研究
ZGC圣经:ZGC垃圾回收器的原理、调优,ZGC 漏标的 分析与 研究
|
11月前
|
存储 JavaScript 前端开发
JavaScript的垃圾回收机制
【10月更文挑战第29天】JavaScript的垃圾回收机制是确保程序高效运行的重要保障,了解其工作原理和相关注意事项,有助于开发者更好地编写高性能、稳定的JavaScript代码。
|
7月前
|
存储 缓存 算法
G1原理—3.G1是如何提升垃圾回收效率
本文深入探讨了G1垃圾回收器提升GC效率的核心机制,包括记忆集(RSet)、位图(BitMap)和卡表(CardTable)的设计与作用。记忆集通过记录跨代引用避免了不必要的老年代遍历,位图用于高效描述内存使用状态以优化标记过程,而卡表则在节约记忆集内存的同时提供更详细的引用信息。此外,文章还解析了DCQ(Dirty Card Queue)和DCQS(Dirty Card Queue Set)机制如何异步更新RSet,确保在高并发场景下的性能与准确性。这些设计共同提升了G1在标记、清理及整理内存时的效率。
277 10

热门文章

最新文章