Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak while running webview2 in WindowsFrom app with runtime version 109 #3678

Closed
ironsoccer21 opened this issue Aug 2, 2023 · 9 comments

Comments

@ironsoccer21
Copy link

Description
Reloading a WebPage in Webview2 control causes memory leak.

Version
WebView2 Runtime version 109.0.1518.49
Build Env : Windows 10 / Visual Studio 2022
Deploy Env : Windows Embedded Standard 7

AppDetails
We built WindowsFromBased App powered by WebView2(Version 109) in Windows10.
The App runs in Windows Embedded Standard 7, and open simple html.
The App keep reloading browser every 30sec by .Reload() function while viewing webpage.

MemLeakDetails
We continuously used the application and measured the memory usage for 7 days.

  • For each "msedgewebview2" instance, the memory usage keeps increasing.

As a result, the application crashed, and all operations became completely unresponsive on Windows 7.

Question
Is there a way to resolve the above memory leak issue?

@LiangTheDev
Copy link
Member

What happened when we reload a page: since it is the same site, we will reuse the same renderer process. And as we are loading a new page, we will create a set of new objects for the new page while the old objects are still alive, waiting for garbage collection to clean them up. GC will happen at its own pace. If we reload or navigate in the same site faster than GC, then we will keep using more memory. If there are leaks in the page or Edge implementation, those leaks will be there until the process is terminated when we navigate away to a different site or close the WebView.

So, things you could try:

  • Call ExecuteScript for window.gc() to trigger GC frequently.
  • Navigate to another “site”, like NavigateToString(“”), and then navigate to the real site again. Note that navigate to about:blank does not count. It will reuse the same renderer process. Navigate to another site will force the platform to use a different renderer process. To avoid showing blank during transition, we might have to use 2 WebViews: navigate webview_2 to the site and switch it to be visible to the user, and then navigate webview_1 to the blank page; navigate webview_1 to site and switch it to be visible to user and navigate webview_2 to blank page, and repeat.
  • Create a new WebView, navigate to the site and switch it to be shown and close the old one. This is similar to option above, but we don’t keep the spare around.

@ironsoccer21
Copy link
Author

Thankyou for your reply.

We'll try using window.gc().
But we have additional questions.

  • Does the memory released by running Windows.gc() only apply to objects under the corresponding window object in JavaScript? For example, is the GC executed for other JavaScript objects as well?

  • Is it possible to define a common GC execution timing for the application? For example, a way to execute GC for all objects once every hour.

@LiangTheDev
Copy link
Member

I have to admit that I am not an expert on how gc works and don't know the details on how it works. Testing suggests that it applies globally. And I could not find a way to define timing for GC. So, just try to trigger it via ExecuteScript and see whether it works. If not, you might have to use other options.

@ironsoccer21
Copy link
Author

Thank you for your suggestion.

We'll try and test how GC works.

@ironsoccer21
Copy link
Author

Thank you for your previous response.

Question:
Are there any other ways to resolve memory leaks besides the three measures you provided?

Here are the measures you provided:
Measure 1:
I executed garbage collection at a shorter interval than the web content reload cycle. Comparing the cases with and without garbage collection, I could confirm that memory was actually released in the short term (1-2 hours) by garbage collection. However, when checking the long-term (several days) running results, memory leaks occurred in both cases. Running GC did not resolve the memory leak issue.

Measure 2:
We are displaying web content with limited resources, and having more than two WebViews constantly running for one web content display would reach the resource limit.

Measure 3:
As you pointed out, a blank screen is displayed every time the web content is reloaded, which does not meet our requirements for the product we want to create.

@ironsoccer21 ironsoccer21 reopened this Sep 26, 2023
@LiangTheDev
Copy link
Member

Have you analyzed the page to see whether there is really a memory leak caused by JS code on the page? If we load the same page in Edge or Chrome browser, and keep reloading it, do you also observe memory usage increase?

Detached elements are a usual cause of leaks. See https://blogs.windows.com/msedgedev/2021/12/09/debug-memory-leaks-detached-elements-tool-devtools/ and https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/memory-problems/dom-leaks for more details on how to do that.

If we could not find the root cause of the leak, you might use some combination of the options, like doing GC, and every 1 hour create a new WebView and switch to use that and close the old one.

@Teletrak
Copy link

I have been experiencing similar problems to ironsoccer21 with a WebView2 implementation that scrapes pages from the same web site. In one run the renderer process memory reached 7GB before the ProcessFailed event reported OutOfMemory. The ExecuteScript("window.gc()") suggestion works well as a solution in this scenario as the scraper does not re-visit pages, and therefore running GC before navigating to a new page (or every n pages) is perfectly feasible. What I wanted to know though, is whether the call to "window.gc()" is only available in DEBUG builds of WebView2.

@LiangTheDev
Copy link
Member

window.gc() is available on release builds of WebView2.

@ironsoccer21
Copy link
Author

Thank you for your reply, LiangTheDev.

In my application, I am not viewing the web content in Edge or Chrome browsers. I am using the WebView2 control within the application to display the web content.

Regarding the HTML file that was displayed in the test where the leak was confirmed, I investigated the detached elements using the method you suggested, but I could not find any detached elements in the relevant HTML file. Therefore, I assume it might be an issue with the WebView2 engine.

For now, I will consider addressing the issue by either performing GC or periodically creating a new WebView, using it, and closing the old one.

Thank you for your assistance.

I apologize for the delayed response, as I was conducting a running test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants