electron: Memory Leak when using Affinity

  • Output of node_modules/.bin/electron --version: v4.0.1
  • Operating System (Platform and Version): Windows 10 Home v1803

Expected Behavior Not leak memory when using affinity

Actual behavior Memory leak only when using affinity

To Reproduce git clone git@github.com:erik-ciq/electron-affinity-leak.git cd electron-affinity-leak && npm install npm run leak

Repo readme has more details.

Screenshots image

image

Additional Information Only requires a single browser window, with affinity, and using location.reload to refresh. Leaks ~ 1.5Mb of memory in renderer process each time. You can run npm start to run the same code without affinity prop set. You’ll see that there is no leak. The leakage only occurs with affinity.

The repo provided also takes heap snapshots at each interval, and provides additional memory usage data if needed.

Probably the base case of https://github.com/electron/electron/issues/12027

There are many similar issues reported in chromium, but it seems like they are related to context leaking from a child iframe into a parent window (causing a strong reference that prevents the iframe from being garbage collected). Here are some links around this for posterity:

https://bugs.chromium.org/p/chromium/issues/detail?id=529941 https://bugs.chromium.org/p/chromium/issues/detail?id=852408 https://bugs.chromium.org/p/chromium/issues/detail?id=270000 https://bugs.chromium.org/p/chromium/issues/detail?id=609137

I also tried to reproduce in chrome using iframes, but it seems like it’s only electron:

https://www.bryntum.com/blog/debugging-memory-leaks-in-web-applications-using-iframes/

Using the gist below, you can cause the chromium leak by holding a reference from the child iframe in the parent window. You can “fix” the leak by removing this reference. Reproduce chromium iframe leak gist

Given that I was able to “remove” the iframe leak by removing the child reference in the parent (from the gist), and given running the repo I created for electron without affinity does not seem to leak, it points towards this being an issue with the affinity implementation in electron.

Diff from electron-quick-start: https://github.com/erik-ciq/electron-affinity-leak/pull/1/files#diff-7a9076d6d94e62c13d641aa71f19ae8eR63

@emmkimme any ideas on what might cause this? Not sure if this is a regression or has existed since https://github.com/electron/electron/pull/11501

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 2
  • Comments: 21 (6 by maintainers)

Most upvoted comments

@MarshallOfSound, Please, this feature is used in our released flagship product. Our product is managing a hundred of pages, Be able to gather some of them in a single process, save memory and prevent to reach the limit of number of processes in Chromium, this is critical for us. We can add the ‘Experimental’ flag on this feature to mitigate the usage. Thanks

I’d like to second the Experimental flag. In a project I’m working on, we’re also using affinity quite extensively. Removing it would almost definitely result in us completely forking Electron to keep the feature (we already have an in-house fork for simpler things).

@MarshallOfSound I second this as well. we have use-case to open multiple windows and using affinity is performant.

@MarshallOfSound, Please, this feature is used in our released flagship product. Our product is managing a hundred of pages, Be able to gather some of them in a single process, save memory and prevent to reach the limit of number of processes in Chromium, this is critical for us. We can add the ‘Experimental’ flag on this feature to mitigate the usage. Thanks

I’d like to second the Experimental flag. In a project I’m working on, we’re also using affinity quite extensively. Removing it would almost definitely result in us completely forking Electron to keep the feature (we already have an in-house fork for simpler things).

I added some additional command line flags to git@github.com:erik-ciq/electron-affinity-leak.git to demonstrate leaking when you close and reopen windows with the same affinity.

Closing a window with affinity (terminating the process), and then opening a new window with that same affinity will produce a leak.

If you use a random affinity each time you close and reopen processes you will not have the leaking issue. It’s only when you re-use affinity. If you close all windows within an affinity to terminate the process, and then follow that by creating a new window with that affinity, you will reap leaked memory equal to whatever was in that same affinity previously.

You can recover the memory for a given affinity by using process.crash in the render. This is the best way I found to recover leaked memory without constantly randomizing affinity: webContents.on('crash', recover); Example of closing and reopening with the same affinity here:

image

^ notice how the memory leak is recovered after the crash.

git@github.com:erik-ciq/electron-affinity-leak.git should have everything people need to investigate their own issues more thoroughly.

@MarshallOfSound, Please, this feature is used in our released flagship product. Our product is managing a hundred of pages, Be able to gather some of them in a single process, save memory and prevent to reach the limit of number of processes in Chromium, this is critical for us. We can add the ‘Experimental’ flag on this feature to mitigate the usage. Thanks

Thanks, @erik-ciq

Is there any update? 😃

This issue is same in Electron v3.x v2.x

We are developing the application which have many sub game windows. So, We should use ‘affinity’ since there is performance issue for many sub windows when we did not use affinity. By the way, This app’s sub windows will be frequently closed and opened by users. So, This memory leak issue with ‘affinity’ is so so super important for us. Please patch the memory leak issue about using affinity.

Actually, I am waiting feedback from #12027

Thanks, Best regards,

@emmkimme Noted, but my opinion still stands. I’ll raise this at the next WG meeting

@MarshallOfSound you mentioned some work on this issue related to a PR you were developing. Is there any status update on that PR?