如何在单页 JavaScript 应用中查找内存泄漏?

4
该应用程序是单页应用程序,因此不需要刷新页面。我们希望将其在Android设备上长时间运行。
但是,我们目前遇到了一个问题:在大约18小时后会崩溃(并且logcat报告指出在Android上运行时出现了OOM错误)。当我使用远程调试并使用Chrome的开发工具捕获时间轴时,很明显我们存在内存泄漏问题,因为我们看到JS堆不断增长。这个堆似乎一直增长,直到我强制进行垃圾回收。
另外一个让我感到奇怪的事情是,我在时间轴上还可以看到我们的事件侦听器正在增加,并且似乎对强制GC没有影响。这就可能是问题本身吗?(根据时间轴,我们谈论着成千上万的侦听器)
除了标准的“3个快照堆分析技术”之外,是否有其他建议?这些技术在此处不太有用,因为即使没有互动,堆也会增长,这可能是由于我们在后台进行的一些周期性更新以读取和显示数据所导致的。否则,我完全可以接受任何其他内存分析工具!
我在这个领域几乎没有经验,因此任何缩小这些恶性泄漏原因的建议都将是极好的!
不幸的是,由于程序的性质和大小,提供有用的代码段非常困难。对于这个长问题,我表示歉意。
编辑: 我最强烈的怀疑之一是当我查看开发工具时间轴并看到侦听器不断增加且未被垃圾回收时……这最终可能会导致崩溃吗?

你看过这个了吗 - https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Memory_Management - Ajaypayne
我之前找到并收藏了它!这是个很好的资源,让我建立了更加坚实的基础知识。我也发现这个链接(https://developer.chrome.com/devtools/docs/javascript-memory-profiling)对于理解谷歌的工具非常有帮助! - originUnknown
1
你在不再需要监听器时是否将其删除?我曾遇到过这样的问题,在我的React应用程序中,我会在组件挂载时添加监听器,但在卸载之前忘记将它们删除,导致一堆不需要的监听器挂在那里。此外,如果组件重新挂载,它会添加另一个监听器,而之前的监听器仍然存在。我可以看出,在一个旨在长时间保持打开状态的应用程序中,这可能会成为一个问题。 - jaredkwright
1个回答

2

朋友,我曾经也制作过单页应用程序,并在其中持续运行某些内容,遇到了你遇到的同样问题。我使用一个无限循环 'while(true)' 来完成某个操作。即使我在循环结束时将变量和对象置空,JavaScript 的 GC 仍未收集垃圾。

解决方案?我将 while(true) 循环更改为定时事件。每隔1秒执行某个操作,使用 JavaScript 的 timeout 方法。

从中我了解到,JavaScript 不会对 while(true) 方法运行 GC。您的代码中是否有类似的情况?

rugs


记住这件事很重要,我们大部分的操作都是有时间限制的,但我一定会检查像这样的循环! - originUnknown

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接