WebBrowser内存问题

我有一个.NET应用程序需要使用WebBrowser来自动浏览一堆页面。 但是,如果我访问Google并设置Google即搜即得,然后搜索任何内容并通过下一个按钮多次手动导航,则我的应用程序使用的内存将开始增加。

问题可能在于Google即时以某种方式保留了以前页面的数据,但即使在我导航到其他地方(例如“about:blank”)后,所用的内存也不会减少。 IE 9也会出现这个问题。我开始写下我在第60页使用的内存,这是我得到的(使用IE 9):

Page 60: 180 MB
Page 70: 214 MB
Page 80: 245 MB
Page 90: 280 MB

正如你所看到的,内存几乎每10页增加30-35 MB。 如果在离开Goog​​le后离开内存,这将不会成为问题。 但不是。

我也试过这个,并没有做任何事情。

编辑:我做了一个项目只是为了测试这个。 这是我的Form1代码:

namespace WebBrowserMemoryTest
{
    public partial class Form1 : Form
    {
        private int _Pages;

        public Form1()
        {
            InitializeComponent();
            webBrowser1.Navigate("http://www.google.com");
        }

        private void startButton_Click(object sender, EventArgs e)
        {
            _Pages = 0;
            timer1.Start();
        }

        private void stopButton_Click(object sender, EventArgs e)
        {
            timer1.Stop();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            HtmlElement next = webBrowser1.Document.GetElementById("pnnext");

            if (_Pages <= 90)
            {
                if (null != next)
                {
                    string href = next.GetAttribute("href");
                    webBrowser1.Navigate(href);
                    _Pages++;
                }
                else
                {
                    timer1.Stop();
                    MessageBox.Show("Next button not found");
                }
            }
            else
            {
                timer1.Stop();
                MessageBox.Show("Done");
            }
        }

        private void goButton_Click(object sender, EventArgs e)
        {
            webBrowser1.Navigate(textBox1.Text);
        }

        private void freeMemButton_Click(object sender, EventArgs e)
        {
            MemoryManagement.FlushMemory();
        }
    }

    public class MemoryManagement
    {
        [DllImport("kernel32.dll")]
        public static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max);

        public static void FlushMemory()
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            if (Environment.OSVersion.Platform == PlatformID.Win32NT)
            {
                SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
            }
        }
    }
}

我做的是搜索在谷歌任何与谷歌即时开启 ,然后按startButton (其中调用startButton_Click )。 大约80页后,我按下stopButton ,然后导航到“about:blank”,然后返回到Google并搜索其他内容,然后再次按下startButton

我首先在我的PC上测试了这个,它有6 GB的内存。 当我达到1.5 GB时,应用程序停止响应,但我没有得到任何OutOfMemory异常。 然后我使用Windows 7和1 GB RAM在虚拟机上进行测试。 当它达到大约300 MB时,我的应用程序中的Web浏览器变得无响应。

如果我按freeMem按钮,它调用freeMemButton_Click ,则内存回落(但看到我的Edit2)。 这样可以“解决”我的问题。 但现在我的问题是为什么我需要调用SetProcessWorkingSetSize ? 它不是Windows应该自动释放内存吗? 另外,我不确定是否调用该函数会有任何副作用。

我很确定这是一个错误。 我应该继续并报告吗?

Edit2:我测试了Stefan的解决方案(调用SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1) )并没有解决它。 内存在任务管理器中停顿下来,但这只是显而易见的。 在没有调用该函数时,应用程序变得无响应之后,应用程序变得无响应。


如果没有理由,Windows并不真正返回释放的内存。 而唯一的原因是如果另一个应用程序需要该内存,并且没有其他可用内存了。 这就是为什么看起来内存使用增加。

尝试打电话

SetProcessWorkingSetSize(GetCurrentProcess(),-1,-1);

有时候 - 这会迫使操作系统将所有释放的内存返回给操作系统。


我认为HtmlElement pnext没有发布,因为它是ComObject,并且Browser Control中可能存在一个错误。

尝试pnext.Release或尝试Marshal.Release并获得ComObject的实例发布。


当使用Webbrowser时,我发现等待“documentcompleted”事件并检查“状态”是否“已完成”是重要的,以便导航没有下一页。 否则取消导航,然后再次等待文档完成状态(中止),然后导航....

可能是使用定时器而不检查Web浏览器的状态可能是一个问题

Webbrowser-Control的下一件事是,你不能在多线程/ Backgroundworker中使用它,因为它需要STA ......(通常会导致无响应的应用程序出现问题)

为我使用.NET的“ful-contol”(解析网站)的解决方案是使用WebRequest / Webresponse,如果您希望DOM“自动”执行,则可以将结果再次投射到Webbroswer.Document,使用它多线程,容易设置超时/代理,我发现比使用Webbrowser控制更舒服。

不过,我成功地在另一个项目中使用提示从这里实现了一个Webbrowser-Control解析页面(如何修复IE WebBrowser控件中的内存泄漏?)

我发现另一个“有趣”的用Winforms编程的细节是,似乎GC.Collect在窗口最小化时被触发,再次打开 - >这是否减少了mem的使用? (也许Stefan的帖子也提到这个问题)

链接地址: http://www.djcxy.com/p/7203.html

上一篇: WebBrowser memory problem

下一篇: Simulate scroll event on iPad