【每日一面】如何解决内存泄漏

news/2025/11/19 10:07:56/文章来源:https://www.cnblogs.com/keepsmart/p/19229280

基础问答

问:有没有遇到过内存泄漏?怎么排查处理的

答:前端页面上出现内存泄露,使用 Chrome devtools -> memory 工具排查,选择时间轴分配(Allocations on timeline)功能后开始录制操作,在页面上进行相关组件的操作,停止录制后,查看内存曲线,重点关注内存曲线上升的和下降的位置,如出现只升不降,没有明显回落的区域,再重点操作,重新录制对应位置的操作,逐步缩小定位。对于这种重点关注的区域,可以同时使用堆快照追踪持续增长的对象。对排查出来的点位进行验证的时候,可以通过内存面板的垃圾回收按钮,如下图,回收后如果内存大小还是很高,可以确认是存在无法回收的内存,有泄露的情况。
image-20251116025955-kdes7f7-tmiqyaxt.png

扩展延伸

内存泄漏是 JavaScript 开发中隐蔽性强且影响严重的问题,尤其在长生命周期应用,如 SPA、后台管理系统中,可能导致页面卡顿、崩溃甚至浏览器无响应的问题。

内存泄露的本质是:本来应该被回收的对象因为意外的引用而保留了下来,导致垃圾回收器无法释放这个对象所占用的内存,使得内存占用持续增长。

垃圾回收机制

JavaScript 采用自动垃圾回收机制,不需要手动释放内存,通过引用计数标记-清除算法回收不再使用的内存:

  • 引用计数:跟踪每个对象被引用的次数,次数为 0 时回收,但是出现循环引用的时候,这个就无法解决了。
  • 标记 - 清除:从根对象(如 window )出发,标记所有可达对象,未被标记的对象将被回收,这是目前浏览器主流的算法。

OOM

和内存泄露相关联的还有一个概念,即OOM,内存溢出,指的是在程序申请内存时,发现没有可用内存分配,直接抛出了 OOM 异常。

一般来说,内存泄露是内存溢出的一个原因,但不是唯一的原因,而内存泄露会持续消耗内存资源,最终导致没有可以分配的内存给程序,出现 OOM。

内存泄露的场景

  1. 意外的全局变量

    一般是在非严格模式下出现,使用的变量没有声明,会隐式的绑定到 window 对象上,变成持久性的引用,如:

    function fn() {data = {};
    }
    

    解决方案:对于这种情况,第一优先的是启动严格模式(现在的框架或项目都是默认为严格模式,通常不需要关注),其次,在现在使用的 es6 规范下,优先使用 let/const​ 关键字声明,最后如果真的是全局变量,我们应该在确定不再使用后,赋值为 null ,从而切断对象的引用,让 GC 自动回收。

  2. 闭包导致内存泄露

    对于前端,闭包是一个非常好用的特性,但同时也需要在使用的时候注意,如果创建的闭包被长期使用,则闭包持有的变量就无法释放,一个经典案例就是计时器:

    function handleOnClickFac() {let timer = null;return function () {timer = setInterval(() => {console.log('hello');}, 3000);}
    }window.clickBtn = handleOnClickFac();btn.addEventListener('click', window.clickBtn);
    

    在这里,每次点击按钮都会触发定时器的创建,但是我们没有清除回收,所以导致这个定时器一直存在,每次点击的时候都会创建一个新的定时器。

    这个例子中,包含两个场景,一是闭包,二是定时器。

    解决方案:限制闭包生命周期,比如这里在 btn 组件卸载时,销毁闭包,从而实现“不可达”的情况,让 GC 回收,其次需要在使用完成后,清除闭包内的引用,在这个例子中,我们不仅要清楚引用,同时还应该清除定时器,否则依旧存在问题。

  3. DOM 元素引用未释放

    分两种情况:1. DOM 树中已经没有 DOM 元素了,但是 JavaScript 中还有这个 DOM 元素的链接(变量),2. 事件监听器没有移除,存在 DOM 和监听回调存在互相引用的情况。

    // 场景1:DOM已删除但 JS 仍引用
    const list = document.getElementById('list');
    const data = { element: list }; // 引用DOM元素
    document.body.removeChild(list); 
    // list已从DOM树移除,但data.element仍引用它,无法回收// 场景2:事件监听器未移除
    const button = document.getElementById('btn');
    button.addEventListener('click', () => {console.log('点击事件');
    });
    // 按钮被删除后,监听器未移除,导致按钮和回调函数都无法回收
    

    解决方案:解决这类场景的核心依旧是在不需要的时候释放引用,不过对于 DOM,还有一种方式就是使用事件委托,从而在子元素删除的时候不受影响。

  4. 第三方库资源未清理

    类似于 Echarts 、地图等库,会要求我们在不使用的时候,调用对应的销毁的 API,如果我们没有调用,这些库创建的临时资源就会持续占用内存,导致内存泄露。

这些场景下的解决方案都是需要我们手动在需要的地方去清除引用,从而使 GC 能够识别并回收内存,通过这些例子也不难发现,虽然在 JavaScript 中不需要我们做类似于 C++ 的手动内存回收,但是依旧需要我们去帮助 GC 更好的判断资源是否需要回收。

检测和分析

内存泄露的检测和分析主要是通过浏览器的内存工具,这里以 Chrome 为例,我们在检测和分析时使用的是 Chrome Devtool Memory 面板:
image-20251116153104-s5tb0qs-scjvtike.png

  1. 观察时间线上的分配(Allocation Timeline)

    1. 开启记录后,按照推测的问题,操作页面内容,完成后停止记录,开始自动分析
    2. 观察只升不降的区域,重复录制该区域对应的操作,查看内存是否确实存在只分配不回收的情况,记录该操作
  2. 记录堆快照(Heap Snapshot)

    1. 操作开始前,记录一次初始的堆快照

    2. 重复第一步记录的操作,拍摄第二次快照,并开启比较(Comparison)模式,重点关注 Delta 和 Retainers 指标(这里对应的面板的中文名是 #增量​ 和 固定装置 ,翻译不是很准确,这里提供英文界面的图作为参考

      image-20251116153926-8vvr07i-edfpjyti.png
      Delta 关注持续增长的对象,Retainer 追踪引用该对象的变量

  3. 点击垃圾桶(代表 GC)触发一次 GC,如果 GC 后内存依旧很高,就可以确认是存在内存泄露。

面试追问

  1. 内存泄露和内存溢出有什么关系?

    内存泄露会导致内存溢出,但是内存溢出不一定是内存泄露导致的。

  2. 常见的内存泄露场景,举个例子?

    参考本文【内存泄露的场景】一节

  3. Node.js 服务中,长生命周期对象持有短生命周期对象是一个典型的泄露场景,举例并给出排查思路

    // 用全局对象做缓存,无淘汰策略
    const cache = {}; // 接口每次请求都往缓存加数据
    app.get('/api/data', (req, res) => {const key = `data_${req.query.id}`;const largeData = fetchLargeData(req.query.id); // 10MB 数据cache[key] = largeData; // 只加不删,缓存持续膨胀res.send(largeData);
    });
    

    由于 cache 没有设置缓存的过期时间、淘汰的方式,导致 largeData 一直被持有,使得内存不断增长。

    排查思路:1. Node.js 应用启动时添加 --inspect 标志,2. 在 Chrome 浏览器中,访问 chrome://inspect 链接对应的 Node 进程,开始监测,3. 记录初始时的堆快照和多次触发后的堆快照,方式参考【检测和分析】一节,4. 查看 cache 的引用路径以及清理逻辑。5. 设置缓存时间或LRU淘汰策略解决这个问题

  4. 线上环境 Nodejs OOM 触发报警了,你应该怎么做?

    首先,应急止损,滚动重启服务,避免损失扩大,同时增加内存延缓 OOM 时间。

    其次,分析问题出现的时间,判断是否可以回滚服务解决。

    最后,分析定位根源,按照服务日志和本地排查手段进行。

    如果使用的是 k8s 等虚化手段,可以配置服务重启规则,避免人工低效的操作方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/969741.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年热门的刀刮布篷布设备最新TOP品牌厂家排行

2025年热门的刀刮布篷布设备最新TOP品牌厂家排行行业背景与市场趋势随着全球户外休闲产业、建筑临时设施和水产养殖业的快速发展,刀刮布篷布设备市场迎来了新一轮增长。据《2024-2029年全球篷布设备市场预测报告》显示…

2025年11月geo优化服务商推荐榜:十大服务商综合实力与行业口碑全解析

本文基于2025年中国信通院行业公开数据和权威第三方Gartner报告,结合推荐对象参考内容,从专业能力、服务品质、技术实力等维度筛选10个推荐对象,旨在提供客观参考。 评选标准:科学维度下的全面审视 本次评选绝非主…

2025年11月豆包搜索排名优化推荐:十大服务商综合评测与技术实力全解析

本文基于2025年中国信通院行业公开数据和权威第三方Gartner报告,结合推荐对象参考内容,从专业能力、服务品质、技术实力等维度筛选10个推荐对象,旨在提供客观参考。评选标准绝非主观臆断,我们建立了严格的四维评估…

2025年新疆残膜回收机公司权威推荐榜单:棉花残膜回收机/北疆残膜回收机/粉杆收膜打包一体机源头厂家精选

随着新疆农业现代化进程的加快和农田环境保护要求的提高,残膜回收机市场呈现稳定增长态势。作为治理农田"白色污染"的关键装备,残膜回收机的技术水平和产品质量直接关系到农业可持续发展水平。本文将基于市…

2025 最新火花机厂家推荐榜:新型 / 镜面 / 数控 / 五轴联动等全品类优选,权威测评助力精密加工选型

引言 在全球精密制造产业升级的浪潮下,火花机作为复杂零部件成型、高精度模具加工的核心设备,市场需求持续保持两位数增长。然而,市场上品牌鱼龙混杂、技术参数虚标等问题,让企业选型面临诸多挑战。本次推荐基于国…

力扣算法 2154题 将找到的值乘以2

力扣算法 2154题 将找到的值乘以2 题目: 给你一个整数数组 nums ,另给你一个整数 original ,这是需要在 nums 中搜索的第一个数字。 接下来,你需要按下述步骤操作:如果在 nums 中找到 original ,将 original 乘以…

2025年11月geo优化公司排行榜:头部服务商技术迭代与长期发展指南

本文基于2025年中国信通院行业公开数据和权威第三方Gartner报告,结合推荐对象参考内容,从专业能力、服务品质、技术实力等维度筛选10个推荐对象,旨在提供客观参考。 评选标准:科学维度下的全面审视 本次评选绝非主…

78.15kW光伏系统采用扰动观察法实现最大功率点跟踪的解决方案

针对78.15kW光伏系统采用扰动观察法(Perturb and Observe, P&O)实现最大功率点跟踪(MPPT)的解决方案一、设计 1. 硬件组成模块 技术参数 功能说明光伏阵列 78.15kW, 600V DC输出 最大功率点跟踪目标DC-DC变换器…

2025年知名的150吨地磅厂家推荐及采购参考

2025年知名的150吨地磅厂家推荐及采购参考行业背景与市场趋势随着物流运输、矿产开采、建筑建材等行业的快速发展,大型称重设备市场需求持续增长。据中国衡器协会2024年发布的行业报告显示,2023年我国地磅市场规模达…

2025年松木猫砂生产厂家权威推荐榜单:无尘矿砂/豆腐猫砂/水晶猫砂源头厂家精选

在宠物用品市场持续增长的背景下,松木猫砂凭借天然环保、高效吸臭、可冲厕降解等特性,成为越来越多养宠家庭的选择。行业数据显示,2025年全球木质猫砂市场年复合增长率预计达10.2%,其中中国市场规模约占全球份额的…

2025年11月geo优化公司排行榜:十大优质服务商综合能力与发展前景指南

本文基于2025年中国信通院行业公开数据和权威第三方Gartner报告,结合推荐对象参考内容,从专业能力、服务品质、技术实力等维度筛选10个推荐对象,旨在提供客观参考。 评选标准:科学维度下的全面审视 本次评选绝非主…

2025年新疆大马力拖拉机公司权威推荐榜单:凯尔3004拉犁/新疆拖拉机/凯尔拖拉机源头厂家精选

随着新疆农业现代化进程的加快和农机补贴政策的持续推动,大马力拖拉机市场呈现稳定增长态势。作为大型农场、农业合作社的主要耕作动力,大马力拖拉机的技术水平和产品质量直接关系到农业生产效率。本文将基于市场数据…

2025年11月geo优化公司排行榜:基于多维度评估的十大优质服务商选择指南

本文基于2025年中国信通院行业公开数据和权威第三方Gartner报告,结合推荐对象参考内容,从专业能力、服务品质、技术实力等维度筛选10个推荐对象,旨在提供客观参考。 评选标准:科学维度下的全面审视 本次评选绝非主…

2025年评价高的GY1B25ADM比例阀厂家最新推荐排行榜

2025年评价高的GY1B25ADM比例阀厂家最新推荐排行榜行业背景与市场趋势随着工业自动化水平的不断提升,比例阀作为流体控制系统的核心元件,在制造业中的应用日益广泛。据《2024-2025中国工业流体控制设备市场研究报告》…

Ubuntu18.04安装Grafana12

Ubuntu18.04安装Grafana12Ubuntu18.04安装Grafana12 一、安装前准备 1.1 更新系统:sudo apt update1.2 安装依赖:sudo apt install -y apt-transport-https software-properties-common wget二、添加Grafana官方APT存…

2025年11月豆包关键词排名优化热度榜:行业头部企业服务能力全景评测

本文基于2025年中国信通院行业公开数据和权威第三方Gartner报告,结合推荐对象参考内容,从专业能力、服务品质、技术实力等维度筛选10个推荐对象,旨在提供客观参考。 评选标准:科学维度下的全面审视 本次评选绝非主…

2025年11月geo公司排行榜:基于行业标准的十大服务商综合排名与选择策略

本文基于2025年中国信通院行业公开数据和权威第三方Gartner报告,结合推荐对象参考内容,从专业能力、服务品质、技术实力等维度筛选10个推荐对象,旨在提供客观参考。 评选标准:科学维度下的全面审视 本次评选绝非主…

11.19工作总结

alpha阶段产品完成上线!完结撒花 新版更新:语言切换功能 卡组系统,社区卡组分享 时间线图片每日凌晨自动生成

2025年11月豆包关键词排名优化对比分析:基于权威数据的十大企业综合评估

本文基于2025年中国信通院行业公开数据和权威第三方Gartner报告,结合推荐对象参考内容,从专业能力、服务品质、技术实力等维度筛选10个推荐对象,旨在提供客观参考。 评选标准:科学维度下的全面审视 本次评选绝非主…