2011-05-27 110 views
7

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

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

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

因此,大家可以看到,内存增加了几乎成线性30 - 每10页35 MB。如果在离开Goog​​le后离开内存,这将不会成为问题。但不是。

我也试过this并没有做任何事情。

编辑:我做了一个项目只是为了测试这个。这里是我的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上测试了这个,它具有6GB RAM。当我达到1.5 GB时,应用程序停止响应,但我没有得到任何OutOfMemory异常。然后我使用Windows 7和1 GB RAM在虚拟机上进行测试。当它达到大约300 MB时,我的应用程序中的Web浏览器变得无响应。

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

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

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

+0

你连接上网络浏览器的任何事件处理程序? – 2011-06-26 06:08:55

+0

没有。只是你看到的代码。 – Juan 2011-06-26 06:40:20

+0

对此有何更新? – atwellpub 2012-03-23 20:51:15

回答

3

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

尝试调用

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

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

+0

在没有Windows释放内存的情况下达到1.5 GB是否正常? – Juan 2011-06-26 04:44:32

+0

请参阅我的编辑。 – Juan 2011-06-26 04:54:15

+0

我运行测试。这并没有解决它。内存看起来是在任务管理器上发布的,但是在没有调用该函数时,在相同数量的浏览器导航变得无响应之后,应用程序变得没有响应。 – Juan 2011-06-27 03:24:06

0

我想的HtmlElement pnext没有被释放,因为它是ComObject,并有可能在浏览器控件中的错误。

尝试pnext.Release或尝试Marshal.Release并获得ComObject的情况下释放。

用的Webbrowser工作时
+0

刚刚尝试添加'if(null!= next)Marshal.ReleaseComObject(next.DomElement);'行到我的'timer1_Tick'方法的末尾,但没有什么区别。达到1 GB。 – Juan 2011-06-26 19:41:18

+0

请在尝试导航之前尝试调用MemoryManagement.FlushMemory – 2011-06-27 06:50:31

+0

我也试过。它不起作用(请参阅我的上次编辑)。 – Juan 2011-06-27 06:52:56

0

,我发现它等待“documentcompleted”事件,并检查“状态”是“已完成” bevore导航没有下一页是很重要的。否则取消导航和文件完毕状态(中止)bevore导航再次等待....

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

与接下来的事情Webbrowser-Control是,你不能在多线程/ Backgroundworker中使用它,因为它需要STA ...(经常会导致无响应应用程序的问题)

解决方案为“ful-contol”(解析网站)使用。 NET对我来说,是使用的WebRequest/WebResponse的,你可以,如果你想要的DOM是“自动”的,其结果再次转换为Webbroswer.Document执行,使用多线程,easyly设置超时s /代理,我发现比使用Webbrowser控制更舒服。

但我成功地实现一个网页浏览器,控制使用提示从这里分析的网页在另一个项目(How to Fix the Memory Leak in IE WebBrowser Control?

另一个“有趣”薄带的WinForms编程我发现是,它似乎是一个GC.Collect的在窗口最小化时触发,再次打开 - >这会减少mem的使用情况吗? (梅比斯特凡的帖子还引用到这个问题)

+0

不幸的是,我尝试了所有这些(链接中的解决方案,尽量减少了应用程序)并且没有任何工作。我甚至尝试擦除TravelLog条目无济于事。 – Juan 2011-07-06 04:21:24