First of all, the concept of memory Leak, memory leakage refers to the program has been dynamically allocated heap memory for some reason is not released or can not be released, resulting in system memory waste, resulting in slow program operation or even system crashes and other serious consequences.
When I recently used WPF WebBrowser, I encountered a memory leak problem.
On the main form, load the form containing the WebBrowser control with a button click event, use this webbrowser to browse the Web page, then call the WebBrowser Dispose () method, and then call Gc.collect (), Finally close the form that currently contains the WebBrowser control.
Use the following code and steps to restore the problem.
MainWindow.xaml
<StackPanelOrientation= "Horizontal"VerticalAlignment= "Top"> <ButtonContent= "Launch Browser window"x:name= "Btnlaunchnewwindow"Margin= "5,0,5,0"Click= "Btnlaunchnewwindow_click" /> <ButtonContent= "Force garbage Collection"x:name= "Btnforcegarbagecollection"Click= "Btnforcegarbagecollection_click" /> <ButtonContent= "Quit"x:name= "Btnquit"Click= "Btnquit_click" /> </StackPanel>
Private voidBtnlaunchnewwindow_click (Objectsender, RoutedEventArgs e) { NewBrowserwindow (). Show (); } Private voidBtnforcegarbagecollection_click (Objectsender, RoutedEventArgs e) {System.GC.Collect (); System.GC.WaitForPendingFinalizers (); System.GC.Collect (); } Private voidBtnquit_click (Objectsender, RoutedEventArgs e) {Environment.exit (0); }
Browserwindow.xaml
<Grid> <grid.rowdefinitions> <RowDefinitionHeight= "Auto" /> <RowDefinitionHeight= "Auto" /> <RowDefinitionHeight="*" /> </grid.rowdefinitions> <StackPanelOrientation= "Horizontal"> <LabelContent= "URL:" /> <TextBoxx:name= "Txturl"Width= "The " /> </StackPanel> <StackPanelGrid.Row= "1"Orientation= "Horizontal"Margin= "0,10"> <ButtonContent= "1." Go/navigate "x:name= "Btngo"Click= "Btngo_click" /> <ButtonContent= "2." Dispose "x:name= "Btnclose"Click= "btnClose_Click"Margin= "10,0" /> <ButtonContent= "3." Force garbage Collection "x:name= "Btnforcegarbagecollection"Click= "Btnforcegarbagecollection_click" /> <ButtonContent= "4." Close window "x:name= "CloseWindow"Click= "Closewindow_click"Margin= "10,0" /> </StackPanel> <WebBrowserGrid.Row= "2"x:name= "WebBrowser" /> </Grid>
Private voidBtngo_click (Objectsender, RoutedEventArgs e) { Try{webbrowser.navigate (NewUri (Txturl.text)); } Catch(Exception ex) {MessageBox.Show ("Exception:"+Ex. Message); } } Private voidbtnClose_Click (Objectsender, RoutedEventArgs e) {Webbrowser.dispose (); } Private voidBtnforcegarbagecollection_click (Objectsender, RoutedEventArgs e) {System.GC.Collect (); System.GC.WaitForPendingFinalizers (); System.GC.Collect (); } Private voidClosewindow_click (Objectsender, RoutedEventArgs e) { This. Close (); }
Steps to reproduce the problem:
STEP1: Starting the program
STEP2: "Launch Browser Window"
STEP3: Enter http://www.msn.com in the address bar (other URLs are also available)
STEP4: Click "1. Go/navigate "button,
STEP5: When the page loads successfully, click "2. Dispose "
STEP6: Click "3. Force Garbage Collection "
STEP7: Click "4. Close window "
Repeat Step2--step7 20-25 times.
The results after several tests are as follows:
After the STEP1 program starts, the memory occupies about 20M (different machines will have some differences),
After repeating step2--step7 20-25 times, the program's memory is around 130M, and the long wait is not released.
Very unlucky to encounter a memory leak problem.
Unlike most WPF controls, WebBrowser controls inherit from HwndHost and use unmanaged resources, so a Dispose () operation on WebBrowser does not work.
The first solution:
The WebBrowser control, which used WinForm earlier, does not have a memory leak, so it is decided to use WinForm's webbrowser instead of WPF. For information about how to host WinForm controls in WPF, see https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/ Walkthrough-hosting-a-windows-forms-control-in-wpf
Second workaround:
WPF WebBrowser is still used, but the second page (BROWSERWINDOW.XAML) is separated into an EXE. Through the main program to call, so when the page is finished, close WebBrowser EXE, its associated memory is all released. If you need to communicate or exchange data between two programs, you can choose wcf/Named pipes.
Reference Links:
Https://stackoverflow.com/questions/2069314/memory-leak-when-using-wpf-webbrowser-control-in-multiple-windows
Https://stackoverflow.com/questions/8302933/how-to-get-around-the-memory-leak-in-the-net-webbrowser-control
WPF WebBrowser Memory Leak problems and temporary solutions