关于内存管理:如何定位内存泄露

100次阅读

共计 1749 个字符,预计需要花费 5 分钟才能阅读完成。

残缺高频题库仓库地址:https://github.com/hzfe/awesome-interview

残缺高频题库浏览地址:https://febook.hzfe.org/

相干问题

  • 垃圾回收机制

答复关键点

垃圾回收 DevTools

内存透露是指不再应用的内存,没有被垃圾回收机制回收。当内存透露很大或足够频繁时,用户会有所感知:轻则影响利用性能,体现为缓慢卡顿;重则导致利用奔溃,体现为无奈失常应用。为了防止内存透露带来的不良影响,须要对垃圾回收机制进行理解,把握内存透露分析方法,欠缺线上相干监控措施。

内存透露定位和剖析个别须要辅助工具,比方 Chrome DevTools。开发者能够通过 DevTools 记录页面流动详情,生成可视化剖析后果,从时间轴中直观理解内存透露状况;利用 DevTools 获取若干次内存快照,查看内存堆栈变动;以及应用 Chrome 工作管理器,实时监控内存的应用状况。

知识点深刻

1. 排查内存透露常见问题

在 JavaScript 中,当一些不再须要的数据依然可达时,V8 会认为这些数据仍在被应用,不会开释内存。为了调试内存透露,咱们须要找到被谬误保留的数据,并确保 V8 可能将其清理掉。

代码量较小时,开发者通常能够基于以下根本准则进行疾速自查:

  1. 是否滥用全局变量,没有手动回收。
  2. 是否没有正确销毁定时器、闭包。
  3. 是否没有正确监听事件和销毁事件。

除此之外,开发者能够借助内部工具进行内存透露排查。

2. 应用 Chrome DevTools 定位内存透露

Performance

关上筹备剖析的页面和 DevTools 的 Performance 面板,勾选 Memory 并开始录制,在模仿用户操作一段时间后完结录制,DevTools 会将这段时间内的页面行为流动进行记录和剖析。

通过生成的后果能够直观查看到内存工夫线,理解内存随工夫的占用变动,如果内存占用曲线成阶梯状始终回升,则可能存在内存透露。按需选取工夫线中的区域片段,查看对应时间段内的流动类型和工夫占用,作为排查和定位内存透露的辅助方法。

Memory

关上筹备剖析的页面和 DevTools 的 Memory 面板,按需生成快照。每个快照的内容是快照时刻,进行一次垃圾回收后,利用中所有可达的对象。

当开发者明确晓得与内存透露关联的用户交互步骤时,能够生成屡次内存快照进行比照,排查出透露的对象:在做用户交互操作之前,进行一次失常内存堆栈信息的快照;在做用户交互操作中或操作完结时,进行内存快照。应用 Comparison 视图或应用 filter 按需查看快照之间的差别。

下面的图中应用 filter 查看快照 2 和快照 3 的差别,通过后果可知在两个快照之间继续被调配 clickCallback 闭包。通过点击文件门路能够定位到内存透露的代码。

3. Node.js 中的内存透露定位

如果须要定位 Node.js 中的内存透露,启动 Node.js 时带上 –inspect 参数,以便利用 Chrome DevTools 工具生成 Memory 快照数据。如图所示,启动 Node.js 服务后,关上 Chrome DevTools,会有 Node 标识,点击能够关上 Node 专用 DevTools。

除此之外,也能够借助第三方包 heapdump 生成快照文件,导入至 Chrome DevTools 中的 Memory 进行快照比照。

启动 Node.js 时带上 –expose-gc 参数以便调用 global.gc() 办法触发垃圾回收。借助 process.memoryUsage().heapUsed 查看内存大小,作为内存透露的辅助判断。

const heapdump = require("heapdump");

const capture = function () {global.gc();
  heapdump.writeSnapshot("./HZFE_HEAPSNAPSHOT/" + Date.now() + ".heapsnapshot");
  console.log("heapUsed:", process.memoryUsage().heapUsed);
};

capture();

/* 可能有内存透露的代码片段 start */
// code
/* 可能有内存透露的代码片段 end */

capture();

参考资料

  1. Chrome DevTools
  2. Fix memory problems

正文完
 0