我正在尝试建立一个环境来检测我的应用程序中的内存泄漏。
应用程序设置:Angular + Electron
模拟应用程序使用:Mocha + Spectron + Webdriverio
我对我在新设置的应用程序上运行的不同用户场景进行了测试,并定期收集每个进程的内存使用情况。
当应用程序处于空闲状态时,内存使用情况符合预期。但是我遇到了其他测试用例的问题。似乎在使用 mocha 运行测试时,我在内存中得到了意想不到的未知结构。这会导致内存泄漏。
我在下面附上了一个截图(开发工具上的内存选项卡),它最能描述我的困惑。
- 快照 1:在设置应用程序后拍摄 ( 81.8 MB )
- 快照 2:在完成一组测试(正常使用约 10 分钟)并且应用程序已返回启动状态后拍摄(109 MB)
- 快照 3:在我强制 GC 后拍摄(通过“收集垃圾”按钮)(108 MB)
比较快照 1 和 2,我可以看到大部分内存在哪里(~19 MB):在字符串中。
检查保持器告诉我这些字符串链接到(全局处理程序)>(GC 根),选择其中一个字符串并$0
在控制台中执行会导致所有字符串的输出相同:<body>...</body>
. 当我将元素悬停时,它会链接到我的应用程序主体(对于每个字符串)。
“扩展字符串结构”给我一种感觉,这是由于某些模块被多次加载并且它的引用从未被破坏(我的猜测是通过Module()
in加载internal/modules/cjs/loader.js:136
)引起的?
当使用“分配时间线”检查内存时,我没有在未释放的内存下找到这个“大字符串对象”,因为相同的操作会导致在“堆快照>比较”下产生新的“大字符串对象”
当我手动模拟测试场景或通过控制台中的函数模拟点击时,没有内存泄漏。
所有这一切都让我想,我做错了或使用了错误的东西(关于摩卡咖啡)。
我的问题:
- mocha 是否不适合这种设置(即在应用程序关闭之前它会保留一些引用)?
- 如果一个结构只被(全局处理程序)>(GC根)保留,它什么时候会被释放?我在这里读到,它们不是您需要担心的事情,但就我而言,它们是:/
- 怎么会有多个字符串(多个引用?),当调用 via 时
$0
,都引用相同的 DOM 元素(<body>
)? - 为什么这个字符串对象在“分配时间线”中不可见?
- 这种类型的内存泄漏可能是什么原因?