none
webBrowser1内存泄漏的问题 RRS feed

  • 问题


  • 我使用c#自带的webbrowser1,发现存在内存泄漏的问题。当webbrowser1载入800多个网页时,该程序的内存占用超过了400M,以下是我的代码:

     this.webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(this.webBrowser1_DocumentCompleted);




           int i2 = 0;
          private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
            {
                if (e.Url.ToString() != webBrowser1.Url.ToString())
                {
                    return;
                }

                i2++;
                Console.WriteLine(e.Url.ToString());
                if (e.Url.ToString().IndexOf("http://news.baidu.com/") >= 0)
                {
                    webBrowser1.Navigate("http://hi.baidu.com/?id=" + i2);
                }
                else
                {
                    webBrowser1.Navigate("http://news.baidu.com/?id=" + i2);
                }

              
    ltxxx
    2009年11月1日 15:21

全部回复

  • 你好!
         如果你载入了800多个页面,占用400M内存也算正常啊!你用IE估计也是一样的效果!
    周雪峰
    2009年11月2日 1:44
    版主
  • 你好,如果你是想抓取页面内容,建议不要使用webBrowser,资源消耗太大。webBrowser主要是用来显示的,估计那800个页面,你可能不是用来浏览的。
    2009年11月2日 1:59
    版主
  • 请看我的代码,每页页面webBrowser1_DocumentCompleted便会跳转到新页面。不是开800多个IE呀。

    我用VC++提供的webBrowser1控件不会暂用超过30M的内存。只有c#会这样。

    ltxxx
    2009年11月2日 4:12


  • 由于项目项目需要支持JavaScript,我需要用webBrowser1抓取页面内容。速度不是关键,只要解决这个内存泄漏的问题就行了。
    或者你又新的webBrowser1类提供不?
    ltxxx
    2009年11月2日 4:14
  • 我使用c#自带的webbrowser1,发现存在内存泄漏的问题。当webbrowser1刷新800次,该程序的内存占用超过了400M,以下是我的代码:

      this.webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(this.webBrowser1_DocumentCompleted);




           int i2 = 0;
          private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
            {
                if (e.Url.ToString() != webBrowser1.Url.ToString())
                {
                    return;
                }

                i2++;
                Console.WriteLine(e.Url.ToString());
                if (e.Url.ToString().IndexOf("http://news.baidu.com/") >= 0)
                {
                    webBrowser1.Navigate("http://hi.baidu.com/?id=" + i2);
                }
                else
                {
                    webBrowser1.Navigate("http://news.baidu.com/?id=" + i2);
                }
    ltxxx
    2009年11月2日 8:55
  • 你好,

    请解释下你的代码的逻辑,和程序是如何加载800多个网页的,可以想到的是程序肯定没有回收一些对象在managed heap,如果你可以让我们重现你的问题,肯定有助于解决这个问题,你还可以参考下这些文章关于使用工具来分析内存的分配情况:
    http://msdn.microsoft.com/en-us/magazine/cc163528.aspx
    Best regards,
    Riquel
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    2009年11月5日 1:51
    版主
  • 以下是我的代码,非常简单:

    创建一个Button1和一个webbrowser1,然后写入代码:


    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;

    namespace testWebbrowser1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }


            int i2 = 0;
            private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
            {
                if (e.Url.ToString() != webBrowser1.Url.ToString())
                {
                    return;
                }

                i2++;
                Console.WriteLine(e.Url.ToString());
                if (e.Url.ToString().IndexOf("http://news.baidu.com/") >= 0)
                {
                    webBrowser1.Navigate("http://hi.baidu.com/?id=" + i2);
                }
                else
                {
                    webBrowser1.Navigate("http://news.baidu.com/?id=" + i2);
                }
            }

            private void button1_Click(object sender, EventArgs e)
            {
                webBrowser1.Navigate("http://news.baidu.com/");
            }
        }
    }



    当i2=800时,发现内存占用了800多M。
    我确定我用的是.NET2.0,我是在release目录下双击运行编译出来的exe。
    ltxxx
    2009年11月9日 9:33
  • 使用Windbg+SOS去debug这个问题,我在i2=200时,通过使用!dumpheap发现多出来了260个System.Object[]对象,你可以使用!GCRoot去看这个对象有没有引用,来分析这个问题。你的代码没有退出条件,他在不停打开网页,分配内存要比回收内存快。


    Best regards,
    Riquel
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    2009年11月10日 7:56
    版主
  • "他在不停打开网页,分配内存要比回收内存快。"

    我在       private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 
    里面加入gc.collect()也解决不了这个问题。

    用vc6.0的webbrowser1插件是没有这种问题的,所以我觉得这是c#的一个bug。
    请问如何再能解决这个问题?我的项目必须解决这个问题。

    ltxxx
    2009年11月10日 8:39
  • 在这种情况下,如果你是想抓取页面内容,直接使用HttpWebRequest和HttpWebResponse。我在32Bit机器下跑上面那段代码,内存只是86,884K(Task Manager下观察),你怎么能是800MB?

    如果你使用GC.Collect方法(我在i2=801时退出循环执行),去调试程序,发现GC的确有回收:

    在一个断点,在调用GC.Collect方法前
    !dumpheap -stat :
    Total 17765 objects

    在下一个断点,在调用GC.Collect方法后:
    Total 5975 objects

    我认为task manager不准确,你需要使用 Process Explorer或Debug等工具来分析内存问题。


    Best regards,
    Riquel
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    2009年11月12日 9:12
    版主
  • 如前面所说,我需要JavaScript支持。所以不能用直接使用HttpWebRequest和HttpWebResponse。
    “我在32Bit机器下跑上面那段代码,内存只是86,884K(Task Manager下观察),你怎么能是800MB?”   -------》继续读下去,内存占用率会继续上升。

    "在下一个断点,在调用GC.Collect方法后:Total 5975 objects"                         ---->这不能说明有内存泄露吗?


    “我认为task manager不准确,你需要使用 Process Explorer或Debug等工具来分析内存问题。"
    ---------------->
    我修改代码 ,用
           public static double GetProcessUsedMemory()
            {
                double usedMemory = 0;
                usedMemory = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0;
                return usedMemory;
            }

            int i2 = 0;
            private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
            {
                GC.Collect();
                Double memoryUsed = GetProcessUsedMemory();

                Console.WriteLine("内存" + memoryUsed);

    依然发现有这个问题,在i2=177时就74M了:
    http://nba.tom.com/?id=177
    已用内存70.35546875
    已用内存74.4921875
    已用内存74.8515625
    http://sports.sina.com.cn/nba/?id=178
    已用内存75.62890625
    已用内存75.6484375
    已用内存75.6484375
    已用内存76.37890625
    已用内存77.08984375
    http://nba.tom.com/?id=179
    已用内存71.53125
    已用内存75.94921875
    已用内存76.12890625
    http://sports.sina.com.cn/nba/?id=180
    已用内存75.921875
    已用内存76
    已用内存76.015625
    已用内存76.7109375
    已用内存77.359375
    http://nba.tom.com/?id=181
    已用内存72.2578125
    已用内存76.22265625
    已用内存76.44140625
    http://sports.sina.com.cn/nba/?id=182
    ......
    http://sports.sina.com.cn/nba/?id=728
    已用内存164.1015625
    已用内存165.578125
    已用内存166.33203125

     

    ltxxx
    2009年11月13日 2:43