How to Fix the Memory Leak in IE WebBrowser Control?

后端 未结 18 720
走了就别回头了
走了就别回头了 2020-11-27 05:33

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

相关标签:
18条回答
  • 2020-11-27 06:03

    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.

    0 讨论(0)
  • 2020-11-27 06:05

    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.

    0 讨论(0)
  • 2020-11-27 06:05

    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);
    }
    
    0 讨论(0)
  • 2020-11-27 06:06

    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();

    0 讨论(0)
  • There is a known Memory Leak in the WebBrowser control. See the following Microsoft KB article - KB893629.

    0 讨论(0)
  • 2020-11-27 06:07

    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

    0 讨论(0)
提交回复
热议问题