WebBrowser проблема с памятью

У меня есть приложение .NET, которое требует использования WebBrowser для автоматической навигации по группе страниц. Но если я перейду, например, в Google и включу Живой поиск Google, а затем выполню поиск по чему угодно и несколько раз перейду вручную через следующую кнопку, объем памяти, используемый моим приложением, начнет увеличиваться.

Проблема может заключаться в том, что Живой поиск 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-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, включенного на , а затем нажимаю кнопку startButton (которая вызывает startButton_Click ). Примерно через 80 страниц я нажимаю кнопку stopButton , затем перехожу к "about: blank", затем возвращаюсь в Google, ищу что-нибудь еще и снова нажимаю startButton .

Сначала я протестировал это на своем ПК с оперативной памятью 6 ГБ. Когда я достиг 1,5 ГБ, приложение перестало отвечать, но я не получал исключения OutOfMemory . Затем я протестировал его на виртуальной машине с Windows 7 и оперативной памятью 1 ГБ. Когда он достиг 300 МБ, веб-браузер в моем приложении перестал отвечать.

Если я нажму кнопку freeMem , которая вызывает freeMemButton_Click , память снова опустится (но посмотрите мой Редактировать2). Так что это «решает» мою проблему. Но теперь у меня вопрос: зачем мне вызывать SetProcessWorkingSetSize ? Разве Разве Windows должна автоматически освобождать память? Кроме того, я не уверен, будет ли вызов этой функции иметь какой-либо побочный эффект.

Я почти уверен, что это ошибка. Должен ли я сообщить об этом?

Edit2: Я протестировал решение Стефана (вызвав SetProcessWorkingSetSize (GetCurrentProcess (), -1, -1) ) и не исправил его. На диспетчере задач вылетела память, но это только видимо. Приложение перестало отвечать после того, как потребовалось столько переходов в браузере, чтобы перестать отвечать, когда эта функция не вызывалась.

7
задан Juan 27 June 2011 в 05:57
поделиться