Запустите элемент управления в отдельном потоке или процессе, чтобы иметь 100% контроль над памятью, которую он потребляет - PullRequest
1 голос
/ 16 октября 2011

Хорошо известно, что элемент управления WebBrowser в некоторых случаях увеличивает использование памяти, не освобождая ее. И крайний случай - навигация по страницам в Google, когда включен Google Instant. Вырастет примерно на 3 МБ на страницу. Эта память не будет освобождена, даже если я перейду к about:blank или если я выберу WebBrowser.

Я знаю, что память в диспетчере задач ненадежна, и есть много способов проверить память, которую использует мое приложение, но поскольку меня действительно заботит предотвращение сбоя моего приложения, я использую MemoryFailPoint класс, чтобы выяснить, сколько памяти у меня осталось. И как мой предыдущий результат , у меня будет на 3 МБ меньше на страницу для использования.

Последний тест, который я провел, состоял в том, чтобы создать форму в моем приложении, где есть только WebBrowser, выполнить поиск в Google с включенным Google Instant, а затем автоматически переходить на следующую страницу каждые 3 секунды. Оставшаяся память будет уменьшаться, и когда она будет близка к 100 МБ, я закрою форму (которая будет располагать WebBrowser) и увижу, что оставшаяся память остается прежней. Я также использовал SOS , чтобы убедиться, что WebBrowser был правильно утилизирован.

GC.Collect() и подобные уловки не освободят память. Установка IE 8 или IE 9 тоже не подойдет. Я не хочу перечислять все, что я пробовал, потому что это сделало бы этот вопрос слишком длинным. Я даже связался с платной поддержкой Microsoft безрезультатно.

С другой стороны, закрытие и перезапуск приложения освободит память. Таким образом, наиболее близким к определенному решению этой проблемы до сих пор является перезапуск приложения.

Итак, мой вопрос: как мне подойти как можно ближе к перезапуску приложения без его фактического перезапуска? Я рассматриваю запуск WebBrowser в отдельном процессе и перезапускаю его по мере необходимости. Проблема в том, что мне нужно, чтобы он был в другой форме, которая могла бы испортить пользовательский интерфейс моего приложения.

Я думаю, что должен быть способ сказать WebBrowser "пожалуйста, уходи, я действительно больше не хочу тебя!" возможно, выгрузив все, что DLL потребляет всю эту память, а затем перезагрузить его. Я ищу крайние меры.

Обратите внимание, что этот вопрос отличается от моего предыдущего . Здесь мне нужно знать не то, как освободить память, используемую WebBrowser (поскольку это невозможно, или, по крайней мере, не существует известного решения), а вообще, если есть способ запустить элемент управления. в «песочнице», а затем очистите эту песочницу. Очень похоже на запуск в отдельном процессе.

Есть идеи?

1 Ответ

1 голос
/ 16 октября 2011

Проверка на обработчики событий ... если вы не удалите их перед закрытием формы, которую они могли бы удерживать, и запретите действительно удалять элемент управления WebbRowser ...

Вы можете попробовать несколько вещей:

  • вызов SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1) после GC.Collect () после Dispose() после удаления любых подключенных обработчиков событий
  • используйте более качественную оболочку, чем встроенная, например этот
  • использует совершенно другую технологию браузера, такую ​​как http://awesomium.com/
...