BrowserContext has a memory leak perhaps.
See original GitHub issueSteps to reproduce
Tell us about your environment:
- Puppeteer version: 1.17.0
- Platform / OS version: Mac OS 10.14.5
- URLs (if applicable): no need
- Node.js version: v9.6.1
What steps will reproduce the problem?
Keep running the code below will cause memory raising slowly. It seams unusual and I don’t how to fix it.
const puppeteer = require('puppeteer');
puppeteer.launch({headless : false}).then(async browser => {
while (true){
let context = await browser.createIncognitoBrowserContext();
await context.close();
}
});
What is the expected result? The memory should be stable.
What happens instead? But it’s keeping raising.
Issue Analytics
- State:
- Created 4 years ago
- Comments:7 (4 by maintainers)
Top Results From Across the Web
Puppeteer: memory leak error and timeout handling
I tried putting the statements inside getData function to be async await but it still opens hundreds of browser instances leading to memory...
Read more >cefsharp/CefSharp - Gitter
My application has a browser that changes back and forth from Visibility. ... There have been quite a few memory leaks fixed recently....
Read more >1148379 - Opt-In Origin Isolation State shouldn't leak between ...
Issue 1148379: Opt-In Origin Isolation State shouldn't leak between BrowserContexts. · 1) Start Chrome Canary. · 2) Open an incognito window and visit...
Read more >chromium/src - Git at Google
BrowserContext contains a DOMStorageContext. BrowserContext's. // destructor posts a message to the WEBKIT thread to delete some of its.
Read more >Your comment is wrong on so many levels: • It's not even on topic ...
Memory profiling and leak tracking is done widely and often (using valgrind, ... I have not "worked on modern browsers" and that seems...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Ok, this took a while to figure.
Summary
This particular example is not a memory leak. This happens because DevTools protocol method
Target.disposeBrowserContext
completes before all browsercontext-related resources are freed. As a result, memory is allocated way faster than it is released.Mitigation
The script is executing a synthetic scenario: usually each context hosts at least a single page it deals with which slows down context creation/disposal and gives enough time for memory disposal. In our tests, real world scenarios do not exhibit this memory starvation behavior.
In ideal world, we can instrument when browsercontext-related resources are getting freed. This is, however, a major engineering effort, that doesn’t worth investment given synthetic nature of the use case.
Investigation
We built a custom chromium version with instrumenting heap profiler for the browser process, and were able to do a few observations with this script:
(All of the memory observations below are done based on the reports of Instrumenting Heap Profiler)
browser.createIncognitoBrowserContext()
/browserContext.close()
commands but keep the browser running, allocated memory is gradually getting freed.slowMo: 100
option), then the memory is stable.We were also monitoring memory consumption with htop - which did not report any memory getting freed in (2). This turned out to be due to the fact that tcmalloc does not return claimed memory back to the system (source#1 and source#2).
This whole behavior seems to be provoked by the lazy initialization and lazy destructuring when creating/disposing browser contexts. Each context sets up a lot of bindings to different mojo components that are gradually destroyed later on. If we create/dispose contexts too fast, then memory is getting allocated faster than it is getting freed.
Afterwords
Chromium team is constantly fighting against memory leaks, but it’s impossible to eliminate them all given the massive Chromium complexity. Unlike renderer processes that are getting recreated, browser process is alive forever, and thus especially susceptible to leaks in the long-run.
@zebulonzh We were initially very frightened by the massive scale of the leak that your script demonstrated. However, investigation revealed that it’s not that bad. To sum up, leaks are likely to be in the browser process; I’d recommend restarting every once in a while if you run at scale.
@derrekyoung restarting browser instance every once in a while is a good thing to do if you run at scale.
The only other thing you can do is to launch a whole new browser.
Adding our confirmation of this bug as well. We’ll spin up 100s of parallel sessions and they’ll kill the VM with OOM. We’re currently killing Puppeteer processes every hour to “solve” the issue.
Any other ideas for creating parallel browser contexts that behave like incognito sessions?