2011-05-27 108 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