Tengo una aplicación .NET que necesita un WebBrowser
para navegar automáticamente por un grupo de páginas. Pero si voy a, por ejemplo, Google y configuro Google Instant, y luego busco algo y navego manualmente a través del siguiente botón varias veces, la memoria utilizada por mi aplicación comenzará a aumentar.Problema de memoria WebBrowser
El problema podría ser que Google Instant está de alguna manera manteniendo los datos de las páginas anteriores, pero incluso después de navegar en otro lugar, como "sobre: en blanco", la memoria utilizada no disminuirá. Este problema también se produce con IE 9. empecé a escribir por mi memoria utilizada en la página 60 y esto es lo que tengo (con IE 9):
Page 60: 180 MB
Page 70: 214 MB
Page 80: 245 MB
Page 90: 280 MB
Así como se puede ver, la memoria aumenta casi linealmente en un 30 - 35 MB cada 10 páginas. Esto no sería un problema si la memoria se liberaría después de navegar fuera de Google. Pero no es.
También probé this y no hice nada.
Editar: Hice un proyecto solo para probar esto. Aquí está mi Form1
código:
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);
}
}
}
}
Lo que hago es buscar cualquier cosa en Google con Google Instant convertido en , y luego presione el startButton
(que invoca startButton_Click
). Después de aproximadamente 80 páginas presiono stopButton
, luego navego a "about: blank", luego regreso a Google y busco cualquier otra cosa y presiono startButton
nuevamente.
Lo probé por primera vez en mi PC, que tiene 6 GB de ram. Cuando llegué a 1,5 GB, la aplicación dejó de responder, pero no obtuve ninguna excepción OutOfMemory
. Luego lo probé en una máquina virtual con Windows 7 y 1 GB RAM. Cuando llegó a unos 300 MB, el navegador web de mi aplicación dejó de responder.
Si presiono el botón freeMem
, que llama al freeMemButton_Click
, la memoria vuelve a bajar (pero vea mi Edit2). Entonces eso "resuelve" mi problema. Pero ahora mi pregunta es ¿por qué tengo que llamar al SetProcessWorkingSetSize
? ¿No se supone que Windows liberará la memoria automáticamente? Además, no estoy seguro si llamar a esa función tendrá algún efecto secundario.
Estoy bastante seguro de que esto es un error. ¿Debo seguir adelante y reportarlo?
Edit2: Probé la solución de Stefan (llamando al SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1)
) y no lo solucioné. La memoria cayó en el administrador de tareas, pero esto es solo aparente. La aplicación dejó de responder después de tantas navegaciones de navegador que dejó de responder cuando no llamaba a esa función.
¿Estás hacer ningún tipo de controlador de eventos en el navegador web? –
No. Solo el código que ves – Juan
¿Alguna actualización sobre esto? – atwellpub