Массовая утечка памяти в ios UIWebView

В поисках утечек памяти в других местах нашей системы я создал веб-страницу объемом 20 МБ с мета-тегом обновления. Идея состояла в том, чтобы переместить много данных через наш код данных, чтобы подтвердить стабильность памяти.

<html>
<meta http-equiv="refresh" content="1">
<body>
<div style="border: 1px solid red">
    Content loading
</div><!-- 20mb worth of comments -->
</body>
</html>

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

Я остановил загрузку обновлений и попытался удалить веб-просмотр.

Я пробовал loadurl:"about:blank", loadhtml:"", закрытие документа javascript.

Я также попытался написать рекурсивный метод removeFromSuperview и removeFromParentViewController, считая, что частное представление прокрутки в веб-представлении является проблемой памяти, но эта память никогда не освобождается. Кажется, я не могу найти надежный способ закрыть веб-просмотр, когда мы закончим с ним.

Мы жили с медленной скоростью просачивания веб-просмотра в течение достаточно долгого времени и действительно хотим найти способ гарантировать, что веб-просмотр может быть полностью очищен, когда мы закончим с ним. Недавно мы конвертировали приложение в ARC, которое не меняло частоту памяти.

Я подумываю попробовать рекурсивный цикл по всем объектам в веб-просмотре и посмотреть, можно ли их освободить. Instruments показывает 20 МБ cfdatas, живой, для каждого обновления страницы 20 МБ, но не показывает их как утечки. если я только доставляю заголовок ответа и выполняю его клиенту urlprotocol, то мы работаем стабильно, поэтому было бы достаточно подтвердить mem leaks в оставшейся части пути к данным, но это такой впечатляющий результат теста, который я надеюсь найти решение для утечки памяти webview однажды и для всех.

У кого-нибудь есть идеи получше, или кто-то пытался вернуться через объекты в uiwebview?

4 ответа

Я избавился от утечки памяти в моем UIWebView, установив его HTML в пустую строку. Единственное место, где это можно сделать, это когда контроллер представления, содержащий веб-представление, исчезает:

- (void) viewWillDisappear:(BOOL)animated {
    if (self.isMovingFromParentViewController) {
        [self.wv loadHTMLString: @"" baseURL: nil];
    }
}

Крик всем разработчикам: Реализация didReceiveMemoryWarning абсолютно необходима при использовании UIWebView!

И это особенно важно, когда UIWebView может перемещаться в любое место или на страницу, которую вы знаете, что приводит к огромным утечкам в UIWebView, например, m.youtube.com.

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

В вашем контроллере представления переопределите didReceiveMemoryWarning следующим образом:

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    [myWebView reload];
}

С iOS 8 и выше вам действительно повезло. WKWebView не протекает и имеет гораздо меньший объем памяти, чем UIWebView, Протестировав его с загруженными изображениями веб-страницами, содержащими сложный Javascript, он показал хорошие результаты

Справочник по классу Apple WKWebView

nshipster на WKWebView

Это не идеально, хотя. Тогда снова, надеюсь, недостатки будут решены вовремя. Ознакомьтесь с советами Синго Фукуямы на GitHub:

WKWebViewTips

  • Слабое "я" в блоках.

Это было одной из важных причин, которые приводят к задержке памяти WebView даже при отключении стека навигации.

Другие вопросы по тегам