JavaScript中的垃圾回收机制负责自动管理内存,回收不再使用的对象所占用的内存空间。在JavaScript中,开发者不需要显式地分配和释放内存,垃圾回收器会自动完成这些操作。以下是关于JavaScript垃圾回收机制的一些关键概念:

1. 内存生命周期:JavaScript内存生命周期包括分配、使用和释放三个阶段。首先,内存会被分配给变量或对象;然后,程序会使用这些变量或对象;最后,不再需要的变量或对象会被垃圾回收器释放。
2. 可达性:垃圾回收器通过可达性来判断一个对象是否还在使用。根对象(如全局对象和其他内置对象)被认为是可达的。如果一个对象可以通过根对象或其他可达对象引用链到达,那么它也被认为是可达的。
3. 引用计数:这是一种较早的垃圾回收策略,通过追踪每个对象的引用次数来判断对象是否仍在使用。当对象的引用计数为0时,表示对象不再被使用,可以被回收。然而,引用计数算法存在循环引用问题,无法回收循环引用的对象。
4. 标记-清除:这是现代JavaScript引擎中常见的垃圾回收算法。标记-清除算法首先会标记所有可达对象,然后遍历整个内存空间,清除未被标记的对象。这种算法可以处理循环引用问题,但可能会导致内存碎片。
5. 分代回收:由于不同对象的生命周期长短不同,现代JavaScript引擎将内存分为新生代和老生代。新生代主要存放短生命周期的对象,老生代主要存放长生命周期的对象。新生代和老生代的垃圾回收策略会有所不同。
6. 增量回收和懒惰回收:为了降低垃圾回收对程序执行的影响,现代JavaScript引擎采用了增量回收和懒惰回收策略。增量回收将回收工作分成多个小任务,穿插在程序执行过程中;懒惰回收则会在一定程度上推迟回收操作,以减少性能开销。

以下是一个简单的示例,演示了 JavaScript 垃圾回收机制中的引用计数和标记清除:

// 引用计数示例
let a = { name: 'John' };
let b = a; // b 引用了 a,a 的引用计数变为 2
a = null; // a 不再引用这个对象,a 的引用计数变为 1
b = null; // b 不再引用这个对象,这个对象的引用计数变为 0,可以被垃圾回收器回收 // 标记清除示例
function foo() {
let x = { name: 'Alice' };
let y = { name: 'Bob' };
x.friend = y;
y.friend = x;
} foo(); // 函数执行完后,x 和 y 都不再被使用,但它们之间相互引用,无法使用引用计数来回收内存
// 垃圾回收器定期运行,会发现 x 和 y 都已经不再被引用,可以被回收

在这个示例中,当变量 a 被赋值给变量 b 时,对象的引用计数变为 2。当 a 被赋值为 null 时,对象的引用计数变为 1。最后当 b 也被赋值为 null 时,对象的引用计数变为 0,可以被垃圾回收器回收。

另外,函数 foo 中创建了两个对象 x 和 y,并且它们相互引用。在函数执行完后,这两个对象不再被使用,但它们之间的引用关系无法使用引用计数来回收内存。因此,垃圾回收器会定期运行,查找那些已经不再被引用的对象,然后释放它们所占用的内存空间。

再来一个例子,我们将创建一些对象并解释JavaScript的垃圾回收机制。

// 创建对象
function createPerson(name, age) {
return {
name: name,
age: age,
};
} // 创建两个对象
let person1 = createPerson("Alice", 30);
let person2 = createPerson("Bob", 35); // person1 和 person2 变量引用了两个新创建的对象,这些对象在内存中是可达的 // 现在将 person1 引用另一个对象
person1 = createPerson("Charlie", 28); // 之前 person1 引用的 "Alice" 对象现在已经不再可达,因为没有变量引用它
// JavaScript的垃圾回收器会识别到这一点,并在合适的时机释放其内存 // 创建一个循环引用
let objA = {
name: "ObjA",
};
let objB = {
name: "ObjB",
};
objA.link = objB;
objB.link = objA; // 将变量设置为 null,打破可达性
objA = null;
objB = null; // 现在 objA 和 objB 对象都不再可达,即使它们彼此引用
// 使用标记-清除算法的垃圾回收器会识别到这一点,并释放它们占用的内存

在这个例子中,我们创建了几个对象并对它们进行了引用。当一个对象不再可达时,它就成为了垃圾回收的目标。对于循环引用的情况,标记-清除算法可以识别到并正确处理这种情况,释放不再使用的对象所占用的内存。

注意:不同的JavaScript引擎可能采用不同的垃圾回收策略,如V8、SpiderMonkey和JavaScriptCore等。

介绍一下js垃圾回收机制的更多相关文章

  1. 前端面试:谈谈 JS 垃圾回收机制

    摘要: 不是每个人都回答的出来... 最近看到一些面试的回顾,不少有被面试官问到谈谈JS 垃圾回收机制,说实话,面试官会问这个问题,说明他最近看到一些关于 JS 垃圾回收机制的相关的文章,为了 B 格 ...

  2. python垃圾回收机制:引用计数 VS js垃圾回收机制:标记清除

    js垃圾回收机制:标记清除 Js具有自动垃圾回收机制.垃圾收集器会按照固定的时间间隔周期性的执行. JS中最常见的垃圾回收方式是标记清除. 工作原理 当变量进入环境时,将这个变量标记为"进入 ...

  3. 谈谈 JS 垃圾回收机制

    谈谈 JS 垃圾回收机制 JS内存泄漏与垃圾回收机制 https://javascript.info/garbage-collection

  4. 浅尝js垃圾回收机制

    局部作用域内的变量,在函数执行结束之后就会被js的垃圾回收机制销毁   为什么要销毁局部变量? => 为了释放内存   js垃圾回收机制何时会销毁局部变量 : 如果局部变量无法再得到访问,就会被 ...

  5. 闭包内的微观世界和js垃圾回收机制

    一.什么是闭包? 官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.相信很少有人能直接看懂这句话,因为他描述的太学术.其实这句话 ...

  6. js 垃圾回收机制和引起内存泄漏的操作

    垃圾回收机制 JS中最常见的垃圾回收方式是标记清除. 工作原理:是当变量进入环境时,将这个变量标记为“进入环境”.当变量离开环境时,则将其标记为“离开环境”.标记“离开环境”的就回收内存. 工作流程: ...

  7. 理解闭包的微观世界和JS垃圾回收机制

    function a() { ; function b() { alert(++i); } return b; } var c = a(); c(); 一.闭包的微观世界 如果要更加深入的了解闭包以及 ...

  8. v8垃圾回收和js垃圾回收机制

    垃圾回收器是一把十足的双刃剑.好处是简化程序的内存管理,内存管理无需程序员来操作,由此也减少了长时间运转的程序的内存泄漏.然而无法预期的停顿,影响了交互体验.本文从 V8 (node.js runti ...

  9. 关于JS垃圾回收机制

    一.垃圾回收机制的必要性 由于字符串.对象和数组没有固定大小,所以当它们的大小已知时,才能对它们进行动态的存储分配.JavaScript程序每次创建字符串.数组或对象时,解释器都必须分配内存来存储那个 ...

  10. js垃圾回收机制

    垃圾回收机制,简称GC(garbage collection),会定期(周期性)地回收那些不再使用的变量,然后释放其内存. 而内存占用的情况有很多: 1.变量 2.字面量对象声明:var obj = ...

随机推荐

  1. springboot项目记录2用户注册功能

    七.注册-业务层 7.1规划异常 7.1.1用户在进行注册的时候,可能会产生用户名被占用的错误,抛出一个异常: RuntimeException异常,作为该异常的子类,然后再去定义具体的异常类型继承这 ...

  2. Core_DataCollect BacNet说明

    /* * BACnet_AI 0 模拟输入.定义一个标准对象,其属性表示模拟输入的外部可见特征. BACnet_AO 1 模拟输出.定义一个标准对象,其属性表示模拟输出的外部可见特征. BACnet_ ...

  3. windows 获取USB,发现安卓设备,转载自www.jb51.net/article/164456.htm

    转载 作者:jgw2008 import win32com.client def CheckDev(): wmi = win32com.client.GetObject ("winmgmts ...

  4. loadrunner获取时间戳

    web_save_timestamp_param("tStamp", LAST);    //取时间戳

  5. python使用zipfile压缩文件,包括空目录

    zipfile压缩文件.包括空目录 # !/usr/bin/python import os import zipfile def zipdir(dirPath=None, zipFilePath=N ...

  6. classload加载机制

    BootstrapClassLoader.ExtClassLoader.AppClassLoader实际是查阅相应的环境属性sun.boot.class.path.java.ext.dirs和java ...

  7. linux查看已知进程PID所在的目录

    pwdx 命令 pwdx PID [was@CMTRMWAS1 ~]$ pwdx 31996 31996: /was/AppServer/profiles/AppSrv03

  8. 手把手教你基于luatos的4G(LTE Cat.1)模组接入华为云物联网平台

    摘要:本期文章采用了4G LTE Cat.1模块,编程语言用的是lua,实现对华为云物联网平台的设备通信与控制 本文分享自华为云社区<基于luatos的4G(LTE Cat.1)模组接入华为云物 ...

  9. Spring--bean管理(easy)

    bean作用范围 利用同一个BookDao设置出来两个不同的对象,得到相同的地址: (默认为单例,即表现为同一个地址) 要是想要得到不同的地址,就需要我们在接口实现类的上面加上这样一个注解:(双例) ...

  10. 孙勇男:实时视频 SDK 黑盒测试架构丨Dev for Dev 专栏

    Dev for Dev 专栏全称为 Developer for Developer,该专栏是声网与 RTC 开发者社区共同发起的开发者互动创新实践活动.透过工程师视角的技术分享.交流碰撞.项目共建等多 ...