0

0

什么是Javascript的垃圾回收机制_怎样避免Javascript中的内存泄漏?

狼影

狼影

发布时间:2025-12-31 14:53:50

|

588人浏览过

|

来源于php中文网

原创

javascript 垃圾回收靠可达性判断对象是否可回收,即从根对象出发标记所有可达对象,未被标记的不可达对象被清除;不依赖引用计数或变量名是否存在。

什么是javascript的垃圾回收机制_怎样避免javascript中的内存泄漏?

JavaScript 的垃圾回收机制靠什么判断对象可回收?

JavaScript 引擎(如 V8)主要用标记-清除(Mark-and-Sweep)机制自动回收内存,不依赖引用计数。它从一组根对象(如全局对象、当前执行上下文中的局部变量、活动函数参数等)出发,递归标记所有可达对象;未被标记的对象即被视为“不可达”,随后被清除。

关键点在于:可达性(reachability)才是决定是否回收的唯一标准,不是“有没有变量名指向它”。比如一个对象被闭包内部函数持有,即使外部变量已设为 null,它仍可达,不会被回收。

常见误判场景:

  • 以为 obj = null 就立刻释放内存 → 实际只是断开一个引用,若还有其他引用(如事件监听器、闭包、缓存 Map 中的 key)仍存在,对象继续存活
  • 认为定时器回调执行完就自动清理其捕获的变量 → 若回调是闭包,且被长期持有的 timer ID 引用(如未 clearInterval),整个作用域链可能滞留
  • 把 DOM 节点和 JS 对象混为一谈 → 移除 DOM 节点不等于解除 JS 引用;若仍有 JS 变量(如 const el = document.getElementById('x'))或事件监听器绑定着它,节点无法被 GC

哪些典型模式会引发内存泄漏?

内存泄漏本质是“本该被回收的对象因意外强引用而持续驻留”。以下是最常踩的坑:

立即学习Java免费学习笔记(深入)”;

  • 未移除的事件监听器:给全局或长生命周期对象(如 windowdocument、单例模块)添加监听器,但组件卸载或逻辑结束时没调用 removeEventListener
  • 闭包中保留大对象引用:回调函数无意中捕获了大型数组、JSON 数据或 DOM 集合,且该回调被长期持有(如挂到定时器、Promise 链、或作为事件处理器未解绑)
  • 全局变量意外增长:忘记用 var/let/const 声明变量 → 自动挂到 window浏览器)或 global(Node.js),例如 data = fetchData()
  • 定时器未清理:使用 setInterval 但忘记 clearInterval,尤其在 SPA 页面切换、React 组件卸载、Vue beforeUnmount 等时机
  • Map/Set 持有 DOM 节点作 key:如 cacheMap.set(domEl, data),DOM 节点被移除后,cacheMap 仍强引用它,阻止 GC;应改用 WeakMap(只接受对象作 key,且是弱引用)

如何用 WeakMap 和 WeakRef 主动降低引用强度?

WeakMapWeakRef 是 ES2015+ 提供的、专为避免内存泄漏设计的工具。它们不阻止垃圾回收,适合做“附属元数据”存储。

优先选 WeakMap 的场景:

Moshi Chat
Moshi Chat

法国AI实验室Kyutai推出的端到端实时多模态AI语音模型,具备听、说、看的能力,不仅可以实时收听,还能进行自然对话。

下载
  • 给 DOM 元素附加私有状态(如拖拽坐标、加载状态),又不想阻止元素被回收
  • 实现对象级缓存,key 是目标对象本身,value 是计算结果

示例:用 WeakMap 缓存 DOM 元素尺寸,无需手动清理

const sizeCache = new WeakMap();

function getCachedSize(el) {
  if (sizeCache.has(el)) {
    return sizeCache.get(el);
  }
  const size = { width: el.offsetWidth, height: el.offsetHeight };
  sizeCache.set(el, size);
  return size;
}

// el 被 remove() 后,sizeCache 中对应 entry 自动失效,无泄漏风险

WeakRef 更底层,适用于需要“尝试访问”一个可能已被回收的对象:

  • 缓存大型资源(如 canvas 上下文、WebGL 纹理),但允许 GC 在内存紧张时回收
  • 实现软引用式观察者模式(需配合 FinalizationRegistry 清理副作用)

注意:WeakRef 不适合常规业务逻辑,API 复杂且时机不可控,WeakMap 覆盖 90% 场景。

调试内存泄漏的实操步骤有哪些?

别猜,用 Chrome DevTools 的 Memory 面板直接观测。核心动作是“对比快照”:

  • 打开 DevTools → Memory → Take heap snapshot
  • 执行疑似泄漏的操作(如打开/关闭弹窗、切换路由、反复增删列表)
  • 再拍一张快照,用 Comparison 视图筛选 “Objects allocated between snapshots”
  • 重点关注 (closure)HTMLDivElementArray 等类型数量是否异常增长
  • 点击某构造函数,在右侧看“Retainers”列 → 找出谁在强引用它(常见是 WindowsetInterval、闭包变量、事件监听器)

命令行辅助排查:

  • console.memory 查看当前 JS 堆大小(单位字节)
  • % gc(V8 内部命令,需开启 --allow-natives-syntax)强制触发 GC,验证是否真泄漏
  • Node.js 可用 process.memoryUsage() 监控 RSS 和 heapUsed

真正难的是识别“间接引用链”——比如一个 setTimeout 回调闭包里用了某个对象,而这个 timer 又被挂到了全局对象上。这种链路必须靠快照 Retainers 一层层点进去看,没法靠代码静态扫描发现。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

454

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

546

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

334

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

82

2025.09.10

chrome什么意思
chrome什么意思

chrome是浏览器的意思,由Google开发的网络浏览器,它在2008年首次发布,并迅速成为全球最受欢迎的浏览器之一。本专题为大家提供chrome相关的文章、下载、课程内容,供大家免费下载体验。

1054

2023.08.11

chrome无法加载插件怎么办
chrome无法加载插件怎么办

chrome无法加载插件可以通过检查插件是否已正确安装、禁用和启用插件、清除插件缓存、更新浏览器和插件、检查网络连接和尝试在隐身模式下加载插件方法解决。更多关于chrome相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

837

2023.11.06

chrome什么意思
chrome什么意思

chrome是浏览器的意思,由Google开发的网络浏览器,它在2008年首次发布,并迅速成为全球最受欢迎的浏览器之一。本专题为大家提供chrome相关的文章、下载、课程内容,供大家免费下载体验。

1054

2023.08.11

chrome无法加载插件怎么办
chrome无法加载插件怎么办

chrome无法加载插件可以通过检查插件是否已正确安装、禁用和启用插件、清除插件缓存、更新浏览器和插件、检查网络连接和尝试在隐身模式下加载插件方法解决。更多关于chrome相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

837

2023.11.06

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

22

2026.03.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Vue 教程
Vue 教程

共42课时 | 9.4万人学习

Vue3.x 工具篇--十天技能课堂
Vue3.x 工具篇--十天技能课堂

共26课时 | 1.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号