【发布时间】:2011-09-03 03:00:15
【问题描述】:
我有一个 .NET 应用程序,它需要使用 WebBrowser 来自动浏览一堆页面。但是,如果我去,例如,谷歌并设置谷歌即时,然后搜索任何东西并通过下一个按钮手动导航几次,我的应用程序使用的内存将开始增加。
问题可能是 Google Instant 以某种方式保留了以前页面的数据,但即使在我导航到其他地方(例如“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。如果在我离开 Google 后释放内存,这将不是问题。但不是。
我也试过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);
}
}
}
}
我所做的是在开启 Google Instant 的情况下在Google 中搜索任何内容,然后按startButton(调用startButton_Click)。大约 80 页后,我按下 stopButton,然后导航到“about:blank”,然后返回 Google 并搜索其他任何内容,然后再次按下 startButton。
我首先在具有 6 GB 内存的 PC 上进行了测试。当我达到 1.5 GB 时,应用程序停止响应,但我没有收到任何 OutOfMemory 异常。然后我在具有 Windows 7 和 1 GB 内存的虚拟机上对其进行了测试。当它达到大约 300 MB 时,我的应用程序中的网络浏览器变得无响应。
如果我按下调用freeMemButton_Click 的freeMem 按钮,则内存会回落(但请参阅我的Edit2)。这样就“解决”了我的问题。但现在我的问题是为什么我需要打电话给SetProcessWorkingSetSize? Windows不应该自动释放内存吗?另外,我不确定调用该函数是否会产生任何副作用。
我很确定这是一个错误。我应该继续举报吗?
Edit2:我测试了 Stefan 的解决方案(调用 SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1))并没有修复它。内存在任务管理器上下降,但这只是明显的。在不调用该函数时,应用程序在浏览器导航多次后变得无响应。
【问题讨论】:
-
您是否在网络浏览器上附加了任何事件处理程序?