question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

BrowserContext has a memory leak perhaps.

See original GitHub issue

Steps 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:closed
  • Created 4 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
aslushnikovcommented, Jul 29, 2019

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)

  1. If we just run the script, the memory allocated on the heap increases drastically.
  2. If we stop issuing browser.createIncognitoBrowserContext() / browserContext.close() commands but keep the browser running, allocated memory is gradually getting freed.
  3. If we slow down creation and destruction of browser contexts (basically, connecting puppeteer instance with the 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.

Keep running the code below will cause memory raising slowly. It seams unusual and I don’t how to fix it.

@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.

We’re currently killing Puppeteer processes every hour to “solve” the issue.

@derrekyoung restarting browser instance every once in a while is a good thing to do if you run at scale.

Any other ideas for creating parallel browser contexts that behave like incognito sessions?

The only other thing you can do is to launch a whole new browser.

1reaction
derrekyoungcommented, Jul 23, 2019

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?

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found