防范并识别 html/JS 应用内存泄漏的策略

·

1 min read

随着时间的推移,内存泄漏会降低应用程序的性能,并可能导致崩溃或其他问题。因此,在应用程序中有效管理内存非常重要。

防范内存泄漏

要防范 HTML/JS 应用程序中的内存泄漏,您可以遵循以下策略:

  1. 避免不必要的引用: 不必要的引用是内存泄漏的常见原因。当不再需要的对象仍被代码的其他部分引用时,就会发生这种情况,从而导致垃圾回收器无法释放这些对象所使用的内存[3]。

     var detachedNode = document.getElementById('someElement');
     detachedNode.parentNode.removeChild(detachedNode);
    

    在上面的示例中,尽管 someElement 已从 DOM 中移除,但由于 detachedNode 中存在对它的引用,所以它仍在内存中。

  2. 合适的事件监听器管理: 不删除事件监听器会导致内存泄漏。当不再需要事件监听器时,请务必将其移除。

  3. 避免使用全局变量: 全局变量不会被垃圾回收器回收,因为它们处于全局范围内。如果全局变量持有对某个对象的引用,则该对象无法被垃圾回收器回收[1]。

  4. 避免闭包引用不需要的数据: 闭包可能会无意中保留对不再需要的较大对象或作用域的引用,从而导致内存泄漏[1]。

      function outerFunction() {
          var largeObject = new Array(1000000).fill('Memory Leak');
          return function innerFunction() {
              return true;
          }
      }
      var closure = outerFunction();
    

    在上例中,innerFunction 的闭包存在于 outerFunction 的作用域里,其中包括 largeObject。尽管 innerFunction 不会使用 largeObject,但由于闭包的存在,只要 innerFunction 存在,它就会保留在内存中。

  5. 避免第三方库的内存泄漏: 某些第三方库可能存在内存泄漏。请始终使用最新版本的库和框架,因为这些版本通常都有内存泄漏修复[1]。

  6. 代码审查: 定期审查代码有助于捕捉常见的内存泄漏模式[1]。

  7. 删除不必要的 DOM 元素: 如果您动态创建了 DOM 元素,但以后不再需要它们,请确保删除它们以及对它们的任何引用[5]。

识别内存泄漏

要识别 HTML/JS 应用程序中的内存泄漏,可以使用以下工具和库:

  1. MemLab: MemLab 是由 Meta(前身为 Facebook)开发的一个开源框架,用于查找 JavaScript 内存泄漏。它能自动检测内存泄漏,并结合特定框架知识来完善泄漏对象列表。MemLab 可以生成驻留追踪(retainer traces),帮助开发人员了解对象未被垃圾回收的原因[6]。

  2. Chrome 开发者工具: Chrome 开发者工具(DevTools) 提供了一系列内存使用情况剖析工具。时间轴视图和配置文件视图(现在是新版 Chrome 浏览器内存面板的一部分)对于发现异常内存模式和识别内存泄漏至关重要。时间轴视图可以显示内存使用量的周期性跳变,而这种跳变在垃圾回收后并不会缩小,从而帮助你发现内存泄漏。分配时间轴/剖析器会周期性拍摄堆快照,帮助你研究可疑的内存分配图[4][7]。

这些工具可以深入了解内存分配和驻留情况,帮助你检测内存泄漏,从而优化代码,提高性能和稳定性。

参考链接

[1] https://nolanlawson.com/2020/02/19/fixing-memory-leaks-in-web-applications/

[2] https://www.ditdot.hr/en/causes-of-memory-leaks-in-javascript-and-how-to-avoid-them

[3] https://blog.logrocket.com/escape-memory-leaks-javascript/

[4] https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/

[5] https://stackoverflow.com/questions/49147182/deleting-html-elements-in-javascript-to-avoid-memory-leaks

[6] https://engineering.fb.com/2022/09/12/open-source/memlab/

[7] https://www.lambdatest.com/blog/eradicating-memory-leaks-in-javascript/