为什么这段代码消耗的内存越来越多?

时间:2010-09-21 08:03:08

标签: c# .net

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/");
        }
    }
}

当我点击Button1(所以它调用button1_Click)并等待大约1小时时,根据任务管理器消耗的ram和label1大约是1000MB(我点击它时大约是20MB)并且增长率有点线性)。 WebBrowser是某种浏览器的alpha版本,任何人都不应该使用它,或者我做错了什么。如果你想知道世界上为什么我想永远导航到这些页面,这只是我遇到的问题的孤立(参见我的另一个问题here)。

编辑:大约一周前,我安装并卸载了IE9测试版。我认为这可能是问题的根源。刚刚在Windows Vista IE8上进行了测试,它的增长不超过80-90MB。我将重新安装Windows,我希望我不需要降级到Windows Vista。

Edit2:我终于找到了问题的原因。它不是IE9测试版。事实是我设置IE不显示任何图片。我认为不显示图片会使导航更快更轻,但显然它激活了一些bug并且消耗的内存开始像疯了一样增长。不过,有了图片,内存增长但速度要慢得多。

3 个答案:

答案 0 :(得分:7)

  

并等待大约10分钟,根据任务管理器消耗的RAM约为200MB

  • 200 MB不是很多
  • TaskManager不适合测量内存使用

您通过控件使用的WebBrowser是IE。它将消耗相当多的内存,主要用于缓存内容。但你的内存确实没有问题。

附加:

我运行了您的应用并仅更改了此方法(添加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));
    }

当我让它运行一段时间内存稳定在75-85 MB范围内。

在评论中提到1.6 GB,这是一个问题。但这不是这个代码。所以你有一个开始:寻找差异。

编辑2

升级您的IE版本。我用Vista / 32和IE8运行它,而WorkingSet不会超过90MB。 (600页)

答案 1 :(得分:4)

  

或我做错了什么

嗯,这不是一个好主意:

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

您在高优先级UI线程中引入了重入紧密循环。我不知道这会在多大程度上妨碍垃圾收集器,但是如果有的话我也不会感到惊讶。基本上你是在滥用UI线程,这必然导致奇怪。 (正如Henk所说,无论如何,10分钟内200MB并不是一个失控的资源泄漏。)

这不是一个好主意。通过添加这样的代码来“隔离”问题并没有帮助。

您已经拥有DocumentCompleted处理程序...为什么不使用那个导航到下一页,而不是这个紧凑的循环?

答案 2 :(得分:2)

我不确定为什么不清楚你为什么要使用大量内存;你无休止地重复加载网页。现在我的浏览器正在使用140megs的内存,而且我不会不断重新加载页面。