none
Memory Leak in IE WebBrowser Control

    Question

  • Ok, I hope this is the correct place to ask this question!

    I originally asked this question in the C# Development forum:
    http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=8&SiteID=1
    but one of the moderators informed me that I needed to ask it in the
    IE Discussion Group
    but one of the moderators there told me that I need to ask it in THIS forum!
    Here is my question:

    This appears to be a common problem, but so far I have not found any answers
    to it.

    I am building a C# application with an IE WebBrowser control in it.
    Whenever I navigate within a page I've loaded in the control, large amounts
    of memory are being used and not released. After 7 hours of use, my app was
    showing a memory use of 900MB, which is simply unacceptable for my clients.

    My question (for myself and all the others who have asked it) is: how can we
    release the memory being used by the WebBrowser control without completely
    shutting down the application? I have tried removing the WebBrowser control
    from it's parent form and calling the dispose() Method on it, but the memory
    is not released. I have confirmed the memory leak/usage with Taskmgr.exe,
    Perfmon.exe, and Process Explorer, all of which show this abnormally high
    memory usage.

    I understand that the memory usage might come in part from circular
    references in the underlying DOM object, but I need a way to manually free
    this memory from time to time.

    If this is in no way possible, then what alternatives do developers have
    (seeing as this memory consumption is not acceptable to many of us)?

    I would really appreciate it, and think it would be great if we can finally
    resolve this issue! Thank you so much for your assistance!

    Again, I apologize if this is the wrong forum, but I was informed
    that this was the place to post this!  Thanks again!

    Friday, November 14, 2008 9:04 PM

All replies

  • What I do is to spawn off a web browser automating program, passing an id via command line. The program reads additional request information from a database based on the id and writes automating result to the database row identified by the id, then exits. 
    Friday, November 14, 2008 10:54 PM
  • I'm not quite sure how this answers my question.  I'm probably just missing something; sorry!
    Monday, November 17, 2008 5:42 AM
  • Aren't you asking for alternatives?
    Monday, November 17, 2008 3:27 PM
  • Ok, I understand what you are saying now; thank you for the suggestion!  However, if many operations are being done on a particular HTML document at regular intervals, it isn't very practical for me to spawn new apps constantly.

    If there is no way to deal with the memory leak in the IE control, I am looking for alternatives to the IE WebBrowser control itself.

    Thanks in advance for your help!
    Tuesday, November 18, 2008 11:22 PM
  • You will thank me for ever for this solution -

    I had couple of application using web browser control and these windows would contineously load new pages. Every time new page loads the application will consume about 5mb memory and would never release it. That would cause the the meory use to go above 1.5 gb in short time causing the application to run slow and finally crash just after couple hours.

    The culprit is IE7. It had severe memory leak issues.

    Solution - Install new browser IE8. All memory leaks plugged. application do not consume any more memory, runs smoothly for hours without crashing Smile

     

    Ajit

     

    Wednesday, November 19, 2008 12:20 PM
  •  

    You can try to navigate to about:blank and next back to the page. In my case a memory ocupied by the IE control will be freed.
    Wednesday, November 26, 2008 5:45 AM
  • Thank you both for the suggestions!  Unfortunately, I am still in the same position; memory is being consumed and never released.  I have updated to IE8 and tried navigating to an about:blank page to no avail.
    Sunday, November 30, 2008 8:25 AM

  • Is the memory released when you minimize the app ?
    If so, try this:

    -- in class definition

            [DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
            internal static extern bool SetProcessWorkingSetSize(IntPtr pProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize);

            [DllImport("KERNEL32.DLL", EntryPoint = "GetCurrentProcess", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
            internal static extern IntPtr GetCurrentProcess();

    -- code to call when you want to reduce the memory

                IntPtr pHandle = GetCurrentProcess();
                SetProcessWorkingSetSize(pHandle, -1, -1);


    • Proposed as answer by studysake Monday, August 15, 2011 6:31 AM
    Wednesday, December 03, 2008 3:45 PM
  •  I've got the same issue and have for a long time.  After the web browser control is used for a while the memory keeps growing and never releases.  Collecting the garbage doesn't work, things are disposed of properly, minimizing the window doesn't work.. the only thing that fixes it is to restart the application.  It will continue to grow until the application crashes.  I haven't found any solutions for this as of yet. 
    Sunday, January 04, 2009 5:42 PM
  • I am having the same issue and I haven't been able to find a solution anywhere. Could be that the WebBrowser control is just cursed to be a memory leaking hog. =( Has anyone found a solution or an alternative control based on another browser?

    Thanks in advance...

    Gnom3
    Thursday, January 22, 2009 7:56 PM
  • I have the same problem, I try to do everything but VM / Memory Size keeping growing

    wb .Dispose();

    wb = null;

    GC.Collect();

    GC.WaitForPendingFinalizers();

    GC.Collect();

    Can someone please give us a hint to solve the problem.

    Wednesday, January 28, 2009 9:24 PM
  • Hello,

    I have this problem too.
    try this page : http://support.microsoft.com/kb/896663
    or this page too : http://support.microsoft.com/kb/943510/
    may be can help you.

    best regards


    Wednesday, February 11, 2009 10:14 AM
  • I can't believe there's no solution to this browser control memory leak issue.  I'm having the same problem and have found no solutions online.  The only choice is to restart the entire process every so often.  Which is soooo 1990's.

    I tried all the GC techniques, which doesn't do anything for the unmanaged memory leak coming from the underlying ActiveX component.  Also tried creating AppDomains to host the browser control.  AppDomains don't seem to separate out the unmanaged memory.  They all share the same pool, which when exited, leaves the leaked memory unchanged.  

    Ugghhhhhhh.  This is way dumb.

    Anyone else have any suggestions?
    Monday, March 16, 2009 10:02 PM
  • This solution worked for me!!
    Thank you so much mike_t2e!!!!!!!

    -----------------------------------------------------------------------

    Is the memory released when you minimize the app ?
    If so, try this:

    -- in class definition

            [DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
            internal static extern bool SetProcessWorkingSetSize(IntPtr pProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize);

            [DllImport("KERNEL32.DLL", EntryPoint = "GetCurrentProcess", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
            internal static extern IntPtr GetCurrentProcess();

    -- code to call when you want to reduce the memory

                IntPtr pHandle = GetCurrentProcess();
                SetProcessWorkingSetSize(pHandle, -1, -1);
    • Proposed as answer by zwars Thursday, June 11, 2009 10:24 AM
    Thursday, April 02, 2009 10:03 PM
  • Thanks, mike_t2e!  Your solution helped me very much!
    • Edited by ept01 Monday, May 25, 2009 12:44 PM
    Monday, May 25, 2009 12:43 PM
  • SetProcessWorkingSetSize doesn't actually release any memory. It does incease the probabilty of the memory being paged out to disk, and probably cause a GC collect.
    Memory leaks like circular reference of javascript objects may not be affected though. Until IE7, IE does not break circular reference automatically.

    MSMVP VC++
    Monday, May 25, 2009 4:01 PM
  • Please DO NOT use script manager and update panel , they have memory leak
    Thursday, October 15, 2009 5:47 PM
  • SetProcessWorkingSetSize doesn't actually release any memory. It does incease the probabilty of the memory being paged out to disk, and probably cause a GC collect.
    Memory leaks like circular reference of javascript objects may not be affected though. Until IE7, IE does not break circular reference automatically.

    MSMVP VC++

    This is true... SetProcessWorkingSetSize doesn't release any memory.
    I don't understand background workings of WebBrowser control, but I realised one thing:
    My program goes through 500 or more pages and reads new content on them. It hogs the RAM quite quickly, and if I run the same function that runs through all those pages again, it simply reads from webbrowser cache, cause it needs only couple of seconds to complete.
    It means that we only need to clear browser cache in order to free RAM. Right? I found this solution, but it doesn't work.

    http://support.microsoft.com/kb/326201/en-us

    It allways gives me PrtectedMemoryException..
    Ok, so how is it possible that the memory is freed only when I close my application, and it's not freed when i dispose my webbrowser control and create new one?
    Sunday, May 30, 2010 10:43 AM
  • Dispose isn't necessary freeing memory. It merely tells the COM server you do not hold the object anymore. The COM server is free to decide when to free memory (e.g. when gc collect or cache expire or wininet session clear)

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    Sunday, May 30, 2010 4:05 PM
  • (reposted here, edited)

    I still have the problem having tried all the fixes here - including using subtasks. Web pages are now becoming so loaded with script the granularity of individual subtasks is becoming an issue. On at least two critical sites memory consumption is so dire I need a better fix. Bad sites can leak around 1Mb per page so after ~2000 pages a 32-bit process is consuming >2Gb and fails.

    Switching off script cures the leaks but breaks some sites. IE8 still has the problem despite the fixes here:
      http://msdn.microsoft.com/en-us/library/dd361842%28VS.85%29.aspx
    In some cases I may be able to change the site script. Does anyone have similar examples of what the site authors should still avoid?

    Is there anything else I can try?

    Will IE9 make further improvements to garbage collection? Might this fix the issue or should I assume not?

    Thanks!
    R.


    Monday, May 31, 2010 2:58 PM
  • Same here. It became even worse with IE7 and IE8. I found out that the Solution with something like:

    SetProcessWorkingSetSize(pi.hProcess, (SIZE_T)-1, (SIZE_T)-1))

    does it for a while, when I do it every 20 navigations.

    Then when the Pagefile-Usage is above a certain limit the application is restarted completely rather fast, so it is freed again.

    Sad story is, that it is in an MFC-CHtmlView, already filled with correction-code from a dozen KB's and the whole app is many years old.

    I hope this horror is soon being solved, on the long run it is getting embarassing to sell software that is based on CHtmlView or WebBrowser2. I got the same problems with doing it with WTL/ATL. After an intensive debugging it is provable, that it happens in Navigate/Navigate2.

    If there is any solution: please, please, please!

    Monday, July 05, 2010 3:34 PM
  • We are now 15 07 2010 . Is there already a solution for this problem?

    This bug prevents developers to make a professional application with this control.

    It's so strange Microsoft can't find an aswser for this?

    Peter Adriaenssens

     

     

    Thursday, July 15, 2010 3:16 PM
  • I met this problem also, and I found that if I minimize the window, the memory will decrease immediately. So I periodically minimize the dialog.
    Saturday, July 17, 2010 3:29 AM
  • That is the same like
    SetProcessWorkingSetSize(pi.hProcess, (SIZE_T)-1, (SIZE_T)-1))
    

    and it also only works correctly on Windows without DirectX-Desktop (pre-vista/7).

    In the meantime we redeveloped the thing with OLE/COM in pure platform-sdk-windows-C-code and removed any framework around. Strangely now it works and doesn't leak anymore. I assume now it is inside MFC and WTL where the wrappers are initialized or the surrounding code for Navigate(2) is called.

    This whole thing is like proving the Fermat-equations :-) Seems like it goes over years and years.

    Friday, August 13, 2010 9:24 AM
  • There is a known memory leak in the WebBrowser control.  See the following Microsoft KB article - KB893629

    Hope this helps!  If you find this post as helpful, please mark it as such.


    If this post is helpful, please mark it as such!
    Dave Black, MCPD, MCTS
    http://dave-black.blogspot.com

    • Edited by Dave Black Wednesday, January 05, 2011 3:45 PM remove duplicate text
    • Proposed as answer by Dave Black Monday, March 14, 2011 2:11 PM
    Wednesday, January 05, 2011 3:43 PM
  •     public void SetSelectedCorridor(string value)
        {
          JavaScriptFun("SelectStationList", value);
          JavaScriptFun("SetStationOption", value);
        }
    
        public object JavaScriptFun(string funName, params object[] args)
        {
          return bFT.Document.InvokeScript(funName, args);
        }
    

    After calling SetSelectedCorridor, the WebBrowser control leaks memory at a rate of about 1 KB/sec.

    The same thing happens when I use an option list input on the page that calls "SelectStationList" when the selected option changes.
    This problem does not happen when the page is loaded in IE 8.

    I have XP service pack 3 so I don't think the KB893629 applies. SP3 applies this patch.

    The one workaround I have found that works is to call webBrowser1.Stop(); after my JavaScript is runs. I invoke a timer handler to run Stop so that
    the page refresh has time to complete before the Stop is called.

    Any idea why my scripts start a constant slow memory leak when running in the WebBrowser control?

    Tuesday, May 10, 2011 8:47 PM
  • I am a little bit new here, but already found a lot of help.

    And also in this post, thanks, thanks!


    IE Prof
    Martijn de Ruiter
    http://www.dehorecaopkoper.nl

    Friday, May 13, 2011 2:34 PM
  • June 2011, IE 9 installed. Still having the problem. 

    Yeahhhhhhhhhhhhhhhhhhhh!

    Monday, June 27, 2011 4:21 AM
  • Thank you very much, this solution work OK in my app.

     

    Thursday, June 30, 2011 4:01 PM
  • This worked for me mike_t2e. Thanks for your solution.
    Monday, August 15, 2011 6:32 AM
  • mike_t2e thanks very much that does seem to clear away some of the cruft.

    As other have indicated it's not a complete solutions but stymies the tide a little.

    I suppose I will have to consider Shengs workarounds in the long term....

    This issue has been on the card for Years and Years now... Ah well.

    Thank for the little help. it helped.

    I came, I saw, I coded
    Wednesday, January 04, 2012 4:25 PM
  • Depending on a person's particular machine, I believe there are two separate issues going on here. First, as several people pointed out, there is a known memory leak in IE7. However, I am running IE8 on Windows 7 64-bit and notice similar but different behavior.

    In my case, when I close my application that has the WebBrowser control, the memory does get released. By definition, a memory leak can't get released without actually rebooting your computer. So the similar phenomenon that is happening with newer versions of IE is not a memory leak. Rather, I would point the finger at .NET's black box garbage collector for being too slow and not recognizing when memory can be release.

    I've read a number of posts that suggest a range of success/failure in using manual calls to GC to release memory. I'm still looking into this. But my main point was not to assume its a memory leak just because huge chunks of memory are getting used up. First check to see if that memory gets released when you shut down your application.

    Monday, February 27, 2012 10:38 PM
  • In my case, when I close my application that has the WebBrowser control, the memory does get released. By definition, a memory leak can't get released without actually rebooting your computer. So the similar phenomenon that is happening with newer versions of IE is not a memory leak. Rather, I would point the finger at .NET's black box garbage collector for being too slow and not recognizing when memory can be release.

    That must belong somewhere else.

    1) We are talking about native, non-.NET- Applications here.

    2) Assuming a windows-platform that can run IE7/IE8: A memory-leakage that is occuring in the storage-region belonging to a certain process is also gone, when that process is gone. Proof that such stuff applies to IWebBrowser2-related things is here: IWebBrowser2's memory not deallocated

    I still think it is in MFC/WTL, because after rewriting the application, so that it NOT uses it, we didn't have the effect anymore.

    Wednesday, February 29, 2012 3:08 PM
  • I had luck with mikes solution coupled with a deconstruction of the controls and disposal of the control before the form is disposed:

    //main form

    bool firstTime = true;

                //to test memory leak in a loop create my flash video player embedded in a web browser control on a winform
                while (firstTime || chkContinuousTesting.Checked) {
                    firstTime = false;


                    string fileName = @"C:\Personal\MPV\TestVideo\Videos\20051210-w50s.flv";
                    FormVideoPlayer frm = new FormVideoPlayer();
                    frm.Play(fileName);
                    frm.ShowDialog(this);
                    frm.Dispose();
                    frm = null;


                    //cleanup to take care of WebBrowser memory leak
                    Win32.MinimizeRelease();
                }

    //on close event from video player form

    private void FormVideoPlayer_FormClosing(object sender, FormClosingEventArgs e) {

                this.Hide();


                //help to clean up web browser memory leak
                webBrowser1.Stop();


                this.SuspendLayout();

                webBrowser1.PreviewKeyDown -= new System.Windows.Forms.PreviewKeyDownEventHandler(this.webBrowser1_PreviewKeyDown); //unregister any events to prevent memory leak
                this.Controls.Remove(this.webBrowser1); //remove the control
                this.ResumeLayout(false);


                webBrowser1.Dispose(); //dispose the control
                webBrowser1 = null;            
            }

    //Win32 Class

    using System;             //Required for Win32Exception
    using System.Runtime.InteropServices;    //Required for DllImport, IntPtr ...
    using System.ComponentModel;


    namespace TestVideo {
        public class Win32 {

    #region Minimize, Memory Release

            [DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
            internal static extern bool SetProcessWorkingSetSize(IntPtr pProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize);


            [DllImport("KERNEL32.DLL", EntryPoint = "GetCurrentProcess", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
            internal static extern IntPtr GetCurrentProcess();


            public static void MinimizeRelease() {
                IntPtr pHandle = GetCurrentProcess();
                SetProcessWorkingSetSize(pHandle, -1, -1);


                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();

          }
            #endregion
        }
    }

    After this fix I ran for many hours without seeing any memory increasing.

    Jason


    Tuesday, March 06, 2012 12:41 AM
  • It is sad to see that there is no working solution yet to this issue.

    Seems that nobody from Microsoft bothered to create a fix for this control.

    Has anyone tried other controls as alternatives in a commercial application.

    Maybe:

    http://code.google.com/p/geckofx/

    http://webkitdotnet.sourceforge.net/

    http://awesomiumdotnet.codeplex.com/

    http://code.google.com/p/open-webkit-sharp/

    Any thoughts?

    Thx,

    Daniel



    -Creator-

    Saturday, September 29, 2012 10:49 AM
  • Has anyone tried any of those WebBrowser components?

    IE webBrowser is useless for my purpose, hoping someone would light my path with an alternative.

    Daniel


    -Creator-

    Monday, October 08, 2012 9:23 AM
  • o_O

    Mike! its Works, very impressive.

    I'm working on an application that uses a webbrowser, I have several tabs in the main html, and whenever sailing including memory increased.

    Now by using this code between the navigation memory is freed.

    Very very thanks!


    SifriG

    Tuesday, December 18, 2012 5:36 PM
  • Daniel:

    As I wrote before, you can use the IWebbrowser2 directly, without a framework. This might be taking some time and for my case I had to rewrite the whole applications GUI. But ... It worked.

    BTW: I retested the problem with the MFC GUI in CHtmlView with VC11 and it still occurs.

    Monday, February 04, 2013 2:52 PM
  • 26.06.2013 -  still the same problem exists :(
    Wednesday, June 26, 2013 11:12 AM
  • this is helpful! Thanks. for sharing!
    Wednesday, September 18, 2013 9:50 PM
  • I have been looking for a solution for this for ages, and finally found one.

    I am using Delphi so the syntax for others may be slightly different

    The code I used is:

    (web1.Document as IPersistStreamInit).InitNew;

    where web1 is a tWebbroser component.

    Hope this helps!



    Monday, November 04, 2013 11:01 AM