使用mocha运行测试会导致内存泄漏和大字符串结构

问题描述

我正在尝试在我的应用程序中建立一个检测内存泄漏的环境

应用设置: Angular + Electron
使用 Mocha + Spectron + Webdriverio

模拟应用使用

我在刚安装的应用程序上运行了针对不同用户场景的测试,并定期收集每个进程的内存使用情况。

当应用程序处于空闲状态时,内存使用情况符合预期。但是我遇到了其他测试用例的问题。 似乎使用mocha运行测试时,内存中出现了意外的未知结构。这会导致内存泄漏。


我在下面附了一个屏幕截图(Memory tab on dev tools),最能说明我的困惑。

  • 快照1:在设置应用程序后拍摄( 81.8 MB
  • 快照2:在一组测试完成(正常使用约10分钟)并且该应用返回到初始状态( 109 MB
  • 后拍摄
  • 快照3:在我强制执行GC(通过“收集垃圾”按钮)后拍摄的( 108 MB

比较快照1和2,我可以看到大部分内存(〜19 MB)在字符串中。

对保留器的检查告诉我这些字符串链接到(全局处理程序)>(GC根),选择其中一个字符串并在控制台中执行$0会为所有字符串产生相同的输出:{{1 }}。当我将元素悬停时,它会链接到我的应用程序主体(针对每个字符串)。

“扩展字符串结构”给我一种感觉,这是由于某些模块多次加载而导致其引用从未被破坏(我猜是通过<body>...</body>中的Module()加载) )?

Expanding string structure

使用“分配时间轴”检查内存时,我没有在未释放的内存下找到此“大字符串对象”,而导致“堆快照>比较”下出现了新的“大字符串对象”的相同操作

当我手动模拟测试场景或通过控制台中的功能模拟点击时,没有内存泄漏。

所有这些使我想,我在做或使用了错误的东西(关于摩卡咖啡)。


我的问题:

  1. 摩卡咖啡是否不适合这种设置(即在应用关闭之前它会保留一些参考)?
  2. 如果仅由(全局处理程序)>(GC根目录)保留结构,则何时将其释放?我读过here,他们并不是您需要担心的东西,但就我而言,它们是:/
  3. 如何通过internal/modules/cjs/loader.js:136调用多个字符串(多个引用?),它们都引用相同的DOM元素($0)?
  4. 为什么这些字符串对象在“分配时间表”中不可见?
  5. 这种类型的内存泄漏可能是什么原因?

解决方法

  1. 不,我不认为这是与摩卡咖啡有关的事情。

技巧是,mocha在nodejs端运行,并使用webdriver协议(HTTP)通过Chromedriver控制浏览器:

enter image description here

我从快照中的字符串可以看到的实际上是从chromedriver发送到您的应用程序中的一些代码。

我相信这是chromedriver的问题。

  1. 当chromedriver尝试执行某些命令时,这可能是页面中的一些注入。

您可以尝试在测试之间清理cookie,本地存储和会话存储,或使用https://webdriver.io/docs/api/browser/reloadSession.html进行硬重装-但是重装相当慢...

或使用https://webdriver.io/docs/api/webdriver.html#refresh

重新加载当前上下文

此外,您可以尝试在应用程序端手动执行一些clenup js代码, https://webdriver.io/docs/api/browser/execute.html