如何正确调试 Electron 内存问题?

Sca*_*olo 15 javascript memory node.js typescript electron

最近,我和我的团队更加关注解决 Electron 应用程序中的高内存使用问题。我们的应用程序有几个渲染器进程,随着时间的推移,当我们的应用程序使用的内存量远不及那么多时,它们最终可能会消耗大量内存。我们很可能需要花费大量时间来追踪此泄漏。

让我对正在发生的事情感到非常困惑的关键是,当在 Chrome Devtools 的内存选项卡上查看时,与我们从活动监视器中提取的值相比,该值似乎完全合理。(以下图片为同时拍摄)

在此输入图像描述

在此输入图像描述

我不太知道从哪里开始了解这些信息。为什么这些数字如此不同?我们的 Web 应用程序是否存在仅通过 Electron 应用程序内存暴露的泄漏?我们使用 Electron 设置来渲染应用程序的方式是否有问题?两者都是吗?

在使用 Electron 时,这种类型的问题似乎很常见,但我一生都找不到资源来开始真正调试这个问题。我不一定要寻找有关我的设置的直接答案,因为我没有直接提供足够的信息。我只是在执行一项事实调查任务,以更好地了解如何在 Electron 生态系统中调试此类问题。

小智 11

我对 Electron 不太了解,但是我喜欢研究和这类问题!我当然没有给你一个明确的解决方案,但我希望其中一些东西可以帮助你调试或在内存问题上取得一些进展。

值得一提的是,您可能会因以下 3 件不同的事情而遇到内存问题:

  • 可能是您自己的代码导致了内存泄漏。
  • 可能是 Electron 导致了内存泄漏。
  • 可能是 Chromium 导致了内存泄漏(因为 Electron 使用 Chromium)。

另一件需要提到的是,这不一定是内存“泄漏”,也可能只是内存膨胀。不同之处在于,内存泄漏时,它会不断泄漏内存,直到崩溃,而内存膨胀时,它会占用所有内存,直到什么都没有剩下,然后才开始从内存中删除旧内容。

从您分享的内容中,如果不进行调试和弄清楚,很难判断问题可能出在哪里。因此,我要做的就是首先确保不是您自己的代码导致泄漏/膨胀,尝试运行代码的一小部分,看看内存是否仍然是问题,然后开始逐步添加更多代码部分,直到你已经添加了所有内容。如果在任何时候内存开始成为问题,则很可能是代码本身(但不一定,那么至少您已经确定了它是什么)。例如,如果您使用的图像组件上的内存突然开始增加,您可以确定这与图像/缓存有关。

您可以尝试的潜在事物

  • 首先调试您的代码以确保它不是您的代码,或者至少准确地查明它是什么(如果它是您的代码)。
  • Check if the images you're using (or other resources) are being cached and if that's what's causing the memory to build up. You could use a cache-control header and disable caching in the dev-tools to make sure there's no caching in a dev environment so you can see if it's the caching.
  • Check if there are any browser settings you can play around with in Electron, I have no idea if you can but if Electron is using Chromium it stands to reason that you should be able to play around with settings like hardware acceleration, disabling it from running in the background and the preload page optimization. Things I read from here: https://ssiddique.info/fix-chrome-memory-leak.html. Or play around with any similar settings you can find.

I believe, intuitively, that the issue is with caching. It seems to me that Electron can use an absurd amount of memory and if it's caching images constantly without deleting it, it will hog up the memory until there's nothing left, before it will start removing old stuff from the cache. What's worse is that if you're using swap/virtual memory and the RAM gets full it will also write those to disk before removing it from RAM, which could also explain an increase in disk space. I'd personally try just disabling all caching and seeing what happens. This is also something you can see here: Changing backgroundImage causes memory leak (Electron). Here is another example: Changing image src constantly / memory usage (Electron), in this case I think the person answering this question probably saw a decrease in memory because of the images not being cached any more when he was using base64 instead. Here is another issue on Chromium: https://forums.raspberrypi.com/viewtopic.php?t=296598, where clearing the ton of cached files also worked. Here, electron memory usage profiling, is another person saying all they were doing was "showing images". Caching is making my spidey senses tingly.

Full boring list of things you can try/look at

https://github.com/electron/electron/issues/21586

There is an open issue in Electron with a memory leak when opening and closing windows.

Event Emitter Memory Leak in Electron App

There is an example of where code itself was causing a memory leak, but it can also be code related to Electron itself.

Memory leak in BrowserWindow, Electron

There is another example of where code can break it and in this case it's also specific to Electron.

chrome and chromium growing memory usage

There is an example of a memory leak caused in chromium, however I have no idea if that was actually an issue since it was never answered.

How to increase the max memory limit for the app built by electron-builder?

You can try to increase/decrease the memory using max-old-space-size.

Another key consideration

The other most viable thing I found was https://seenaburns.com/debugging-electron-memory-usage/, who eventually came to the conclusion that it had something to do with RSS (and also caching). This person, https://spectrum.chat/electron/general/debugging-high-memory-usage-in-electron~80057ff2-a51c-427f-b6e1-c297d47baf5b, also mentioned it's relative to RSS and I also found an open issue for electron here: https://github.com/electron/electron/issues/25208, which is related to an RSS memory leak.

Final note

Electron will use a ton of memory because it's running a full browser inside a browser/desktop, Chromium, along with running v8 and all of it's own code. Along with that Chromium is already known for high memory usage. So it's relatively normal to see high memory. Along with that if the memory is just bloating, it's an easier issue to solve by pinpointing what's bloating it, which is very likely something like a cache. If it's a memory leak then it could be anything, your own code most likely, but it could also be an official bug in either Electron or Chromium.

If all else fails you could just jump on the https://www.reddit.com/r/programming/comments/7p7s8q/electron_is_cancer/ bandwagon. In my experience things written in Electron are incredibly slow, memory intensive and don't survive in a browser, Discord and Slack being the biggest culprits. I can leave open any apps in my browser for days with no issues but leaving either of those will eventually crash my browser. Zoom is a bit better but that's likely because of them using their own SDKs and only using Electron as an interface while atom is also better than most apps but as one of the top comments on that post points out, they've rewritten some of the core parts in c++. I don't know much about Electron so I have no credible opinion on it, but the apps I use built using Electron always have the same memory issues. I think that Electron is an awesome idea and concept and that the apps have improved a lot over time, so respect to those teams working on it, but I also think it still has a lot of issues to sort out, especially when it comes to memory.