tags:

views:

303

answers:

3
public partial class Form1 : Form
{
    bool AfterDocumentCompleted = false;
    int steps = 0;

    public Form1()
    {
        InitializeComponent();
        webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(DocCompletedHandlerCopy);
        webBrowser1.ScriptErrorsSuppressed = true;
    }

    private void DocCompletedHandlerCopy(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        if (webBrowser1.ReadyState == WebBrowserReadyState.Complete && e.Url == webBrowser1.Url)
        {
            AfterDocumentCompleted = true;
        }
    }

    private void NavigateAndWait(string urlString)
    {
        AfterDocumentCompleted = false;
        webBrowser1.Navigate(urlString);
        while (AfterDocumentCompleted == false) Application.DoEvents();

        steps += 1;
        label1.Text = string.Format("{0:00000} / {1}MB", steps, Environment.WorkingSet / (1024 * 1024));
    }

    private void button1_Click(object sender, EventArgs e)
    {
        while (true)
        {
            NavigateAndWait("http://www.crucial.com/");
            NavigateAndWait("http://www.google.com/");
            NavigateAndWait("http://www.microsoft.com/");
            NavigateAndWait("http://www.stackoverflow.com/");
            NavigateAndWait("http://www.yahoo.com/");
        }
    }
}

When I click Button1 (so it calls button1_Click) and wait for about 1 hr, the ram consumed according to Task Manager and label1 is about 1000MB (is about 20MB as soon as I click it and the rate of grow is somewhat linear). Is the WebBrowser some kind of alpha version of a browser that is not supposed to be used at all by anyone, or am I doing something wrong. If you wonder why in the world do I want to navigate for ever to those pages, this is just the isolation of a problem I was having (see my other question here).

Edit: About a week ago I installed and uninstalled IE9 beta. I think that might have originated the problem. Just tested it on a Windows Vista IE8 and it didn't grow any bigger than 80-90MB. I'll just reinstall Windows and I hope I don't need to downgrade to Windows Vista.

Edit2: I finally found the cause of the problem. It was not IE9 beta. It was the fact that I set IE not to show any pictures. I thought not showing pictures would make navigation faster and lighter, but apparently it activated some bug and the memory consumed started growing like crazy. Still, with pictures the memory grows but a lot slower.

+4  A: 

or am I doing something wrong

Well, this is not going to be a good idea:

while (AfterDocumentCompleted == false) Application.DoEvents();

You're introducing reentrancy and a tight loop in the high priority UI thread. I don't know to what extent that will hamper the garbage collector, but I wouldn't be surprised if it did. Basically you're abusing the UI thread, which is bound to cause oddities. (As Henk says, 200MB in 10 minutes isn't exactly a runaway resource leak anyway.)

This just isn't a good idea. "Isolating" a problem by adding code like this isn't going to help.

You already have a DocumentCompleted handler... why not use that to navigate to the next page, instead of this tight loop?

Jon Skeet
Hm, but that doesn’t explain runaway memory consumption...
Timwi
Jon, DoEvents has its problems but how would this block Invoked actions?
Henk Holterman
@Timwi: All kinds of odd things may happen when you put the system into a crazy situation like this though.
Jon Skeet
Try changing it to only load the next page AFTER DocCompletedHandlerCopy gets called. Just see what happens
colithium
@Henk: Yeah, my mistake on that front - have edited :)
Jon Skeet
@colithium: Yes, I was just thinking that myself :)
Jon Skeet
Can you suggest another way of making a function `NavigateAndWait`? I would greatly appreciate it.
jsoldi
@jsoldi: I wouldn't make it wait at all. I'd use the UI thread reactively, which is what it's been designed for. If you want to loop through, navigating with the browser constantly, then navigate in the DocumentCompleted event but don't loop waiting until it's finished.
Jon Skeet
Yea maybe I should change tons of code to make it that way but would that fix the memory problem?
jsoldi
No, it won't. You don't really have a memory problem.
Andrew Barber
@colithium: Seems to me that it IS navigating after `DocCompletedHandlerCopy` returns. This is not multi thread. `NavigateAndWait` calls `DoEvents` and `DoEvents` calls `DocCompletedHandlerCopy` so `NavigateAndWait` doesn't return until `DocCompletedHandlerCopy` have returned.
jsoldi
@jsoldi From the docs: "Navigate asynchronously to the document at the specified Uri." This comment thread is getting a bit out of hand haha
colithium
@jsoldi: But there's no need to have a loop. Just navigate *in the event handler*.
Jon Skeet
+2  A: 

I'm not sure why it would be unclear why you are using lots of memory; you are reloading web pages over and over again endlessly. Right now my browser is using 140megs of memory, and I'm not reloading pages constantly.

Andrew Barber
Please see my comment at Henk Holterman's answer.
jsoldi
+7  A: 

and wait for about 10 minutes, the ram consumed according to Task Manager is about 200MB

  • 200 MB is not a lot
  • TaskManager is not suitable for measuring memory use

The WebBrowser you use through the control is IE. It will consume quite a bit of memory, mostly to cache content. But you don't really have a problem with memory.

Additional:

I ran your App and changed only this method (add Label1) :

    int counter = 0;

    private void NavigateAndWait(string urlString)
    {
        AfterDocumentCompleted = false;
        webBrowser1.Navigate(urlString);
        while (AfterDocumentCompleted == false) Application.DoEvents();

        counter += 1;
        label1.Text = string.Format("{0:000} {1}", counter, 
           Environment.WorkingSet/ (1024*1024));
    }

When I let it run for a while Memory stabilizes at a 75-85 MB range.

In a comment you mention 1.6 GB, that is a problem. But that was not with this code. So you have a start: look for the differences.

Edit 2

Upgrade your version of IE. I am running this with Vista/32 and IE8 and the WorkingSet won't go over 90MB. (600 pages)

Henk Holterman
Do I really have to wait until it reaches 1g? Actually, it already reached 1.6g on the real version of the program. Then my mouse kinda stopped working so I just stopped it. Is the mouse not working and getting Out Of Memory exceptions suitable enough for measuring memory use?
jsoldi
@jsoldi: What is the real application doing? Knowing that we might come up with a suitable workaround. Checking web pages using the browser control in a tight loop like this seems not like something you would do in a real application as long as you are sane.
0xA3
It's a web scraper. Gets information from web pages. You would probably tell me to use a `WebClient` and an HTML parser, but I need to fill forms with JavaScript and stuff like that. I know I can still use a `WebClient` but it would be just way more complicated.
jsoldi
@jsoldi: see my Edit.
Henk Holterman
I'm trying your code. I'll let it run for longer and see what happens. Thanks.
jsoldi
Tried it. It reaches 1g after about 1 hr and about 2500 steps. My original application didn't grow any faster that this, so the problem is right here. I'm thinking the problem is with a leak in IE as 0xA3 suggested. I'm using IE 7 and windows vista, .net 4.0. I'll try disposing the WebBrowser and using a new one every time, see what happens.
jsoldi
Alright. The disposing _might_ help, but since it is largely unmanaged code it is not guaranteed. And please add those details to the question.
Henk Holterman
Oh, sorry I meant IE8. My bad. Wonder if it has something to do with installing IE9 beta (that I already uninstalled, for sure). I'm not sure if I had this problem before that. Might need to reinstall Windows.
jsoldi
Did you actually tried it with the same web pages as I did? I just installed Windows Vista 64 and this are a few steps/MB's over time: 103/111, 343/167, 860/304. About 2.5 steps per MB, which is about the same I was getting before (2500 steps/1g). Please let me know about the web pages you used. Thanks.
jsoldi
I used your table. Unaltered.
Henk Holterman