I am trying to embed a WebBrowser Control in a C# Winform Application. This sounds easy enough. However I discovered that the WebBrowser control eats up a lot of memory ever
I was running into the same problem, as an alternative, instead of navigating to a new page, I simply rewrote the same html page using the system.oi.streamreader/writer object and calling a refresh. Obviously that won't work in a situation where content for the browser is being fed online, but it's doing the trick for me.
Also, I'm currently using 8+ browser controls all active at the same time to serve reporting through javascript inside my .net app. As a user makes one browser active, the html to which the other browsers are pointing, are cleared and the browsers refreshed. With 8 browsers running with these two methods I can easily keep my app well under the memory usage of Firefox with just 3 tabs open.
I had same similar problems. I was sending more than 5000 navigation requests via web browser to scrape dynamic pages. After about 50 request, I would run out of memory as navigation request memory usage was not released after each request. I used webBrowser.Dispose() after the navigation, and it solved the problem. It does not have to do with IE7 or so. I am using IE 11 and got same problem. It was because I was not disposing the navigation Objects. Hope this helps.
Just declare the WebBrowser control using the "using" keyword. It will stop leaking memory when calling the Navigate() method anymore. I just tested it and it worked fine for me.
using (var webBrowser = new System.Windows.Forms.WebBrowser())
{
webBrowser.Navigate(url);
}
I just created a simple app with a web browser control to try and duplicate your results. What I found was that yes, every time you navigate to a page, the memory being used increases significantly. HOWEVER, this is NOT a memory leak, because if you keep navigating, you'll see that after a short while, the memory drops significantly, indicating that the garbage collector did it's thing. To prove it, I forced the Garbage Collector to collect after every time I called Navigate, and the overall memory used stayed put at almost the same amount after every navigate call.
So while it DOES rack up memory every time you "Navigate" it's NOT a memory leak, and you the memory will be released. If it's raking up too quickly, just call GC.Collect();
There is a known Memory Leak in the WebBrowser control. See the following Microsoft KB article - KB893629.
I looked all over the internet and I was unable to find an answer to this problem. I fixed it using the below:
Protected Sub disposeBrowers()
If debug Then debugTrace()
If Me.InvokeRequired Then
Me.Invoke(New simple(AddressOf disposeBrowers))
Else
Dim webCliffNavigate As String = webCliff.Url.AbsoluteUri
'Dim webdollarNavigate As String = webDollar.Url.AbsoluteUri
Me.splContainerMain.SuspendLayout()
Me.splCliffDwellers.Panel2.Controls.Remove(webCliff)
Me.splDollars.Panel2.Controls.Remove(webDollar)
RemoveHandler webCliff.DocumentCompleted, AddressOf webCliff_DocumentCompleted
RemoveHandler webDollar.DocumentCompleted, AddressOf webDollar_DocumentCompleted
RemoveHandler webCliff.GotFocus, AddressOf setDisposeEvent
RemoveHandler webCliff.LostFocus, AddressOf setDisposeEvent
RemoveHandler webDollar.GotFocus, AddressOf setDisposeEvent
RemoveHandler webDollar.LostFocus, AddressOf setDisposeEvent
webCliff.Stop()
webDollar.Stop()
Dim tmpWeb As SHDocVw.WebBrowser = webCliff.ActiveXInstance
System.Runtime.InteropServices.Marshal.ReleaseComObject(tmpWeb)
webCliff.Dispose()
tmpWeb = webDollar.ActiveXInstance
System.Runtime.InteropServices.Marshal.ReleaseComObject(tmpWeb)
webDollar.Dispose()
webCliff = Nothing
webDollar = Nothing
GC.AddMemoryPressure(50000)
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForFullGCComplete()
GC.Collect()
GC.RemoveMemoryPressure(50000)
webCliff = New WebBrowser()
webDollar = New WebBrowser()
webCliff.CausesValidation = False
webCliff.Dock = DockStyle.Fill
webDollar.CausesValidation = webCliff.CausesValidation
webDollar.Dock = webCliff.Dock
webDollar.ScriptErrorsSuppressed = True
webDollar.Visible = True
webCliff.Visible = True
Me.splCliffDwellers.Panel2.Controls.Add(webCliff)
Me.splDollars.Panel2.Controls.Add(webDollar)
Me.splContainerMain.ResumeLayout()
'vb.net for some reason automatically recreates these and the below is not needed
'AddHandler webCliff.DocumentCompleted, AddressOf webCliff_DocumentCompleted
'AddHandler webDollar.DocumentCompleted, AddressOf webDollar_DocumentCompleted
'AddHandler webCliff.GotFocus, AddressOf setDisposeEvent
'AddHandler webCliff.LostFocus, AddressOf setDisposeEvent
'AddHandler webDollar.GotFocus, AddressOf setDisposeEvent
'AddHandler webDollar.LostFocus, AddressOf setDisposeEvent
webCliff.Navigate(webCliffNavigate)
'webDollar.Navigate(webdollarNavigate)
disposeOfBrowsers = Now.AddMinutes(20)
End If
End Sub
I know this is not the prettiest or perfect solution, but it worked very well for me. -- Layla