К сожалению, я попробовал все это (решения в вашей ссылке, сворачивая приложение), и ничего не получалось. Я даже пытался стереть записи TravelLog безрезультатно.
я есть приложение .NET, которое нуждается в использованииWebBrowser
для автоматической навигации по куче страниц. Но если я зайду, например, в Google и включу Google Instant, а затем выполню поиск чего-либо и несколько раз вручную нажму следующую кнопку, объем памяти, используемой моим приложением, начнет увеличиваться.
Проблема может заключаться в том, что 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
Итак, как вы можете видеть, объем памяти увеличивается почти линейно на 30 - 35 МБ каждые 10 страниц. Это не будет проблемой, если память будет освобождена после того, как я уйду из Google. Но это не так.
Я тоже пробовалэто и ничего не делал.
Редактировать: Я сделал проект, чтобы проверить это. Вот мой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 с включенным Google Instantна, а затем нажмитеstartButton
(который вызываетstartButton_Click
). Примерно после 80 страниц я нажимаюstopButton
, затем перейдите к «about: blank», затем вернитесь в Google, найдите что-нибудь еще и нажмитеstartButton
очередной раз.
Я сначала проверил это на своем ПК, который имеет 6 ГБ оперативной памяти. Когда я достиг 1,5 ГБ, приложение перестало отвечать, но я не получилOutOfMemory
исключение. Затем я проверил его на виртуальной машине с Windows 7 и 1 ГБ оперативной памяти. Когда он достиг примерно 300 МБ, веб-браузер в моем приложении перестал отвечать на запросы.
Если я нажмуfreeMem
кнопка, которая вызываетfreeMemButton_Click
, память возвращается вниз (но см. мой Edit2). Так что это "решает" мою проблему. Но теперь мой вопрос: зачем мне звонитьSetProcessWorkingSetSize
? Разве Windows не должна автоматически освобождать память? Кроме того, я не уверен, что вызов этой функции будет иметь какой-либо побочный эффект.
Я уверен, что это ошибка. Должен ли я пойти дальше и сообщить об этом?
Edit2: Я проверил решение Стефана (звонитSetProcessWorkingSetSize(GetCurrentProcess(), -1, -1)
) и не исправить это. Память у менеджера задач опустилась, но это только очевидно. Приложение перестало отвечать на запросы после того, как многие браузеры перестали отвечать, когда не вызывали эту функцию.