Грязная память ImageIO не очищается автоматически iOS

Я создаю приложение, которое представляет собой своего рода галерею - оно показывает различный медиаконтент в полноэкранном режиме просмотра. Инструмент распределения показывает, что параметр Live Bytes не превышает 40 Мб при использовании приложения. Между тем приложение на 100% убивается после того, как я пролистываю страницы 20-30 раз. Я проверил параметр Dirty Memory и обнаружил, что он в 10 раз больше размера Live Bytes. И большая часть этой грязной памяти потребляла Image IO:

Снимок экрана

РЕДАКТИРОВАТЬ, еще один снимок экрана:

Снимок экрана

Вышеуказанные пики распределения предназначены для переключения мультимедийного содержимого видео / изображений. Проблема в том, что грязная память растет почти линейно, и мне нужно как-то ее освободить.

Теперь о дизайне приложения. Экран приложения имеет одну горизонтальную прокрутку. Просмотр с прокруткой содержит видео или объекты коллажа, содержащие несколько изображений. Для экономии памяти одновременно создаются только три страницы - текущая страница и страницы слева / справа. Таким образом, страницы всегда создаются и удаляются на лету при скользящей прокрутке.

Все изображения загружаю методом [UIImage imageWithContentOfFile: path]. Объект Collage хранит экземпляры UIImage внутри imagesArray. В методе dealloc атрибут imagesArray очищается.

Итак, вопросы:

  • Это какая-то системная ошибка в [UIImage imageWithContentOfFile?]
  • Это кеш Image IO?
  • Могу я его очистить?

person ZAN    schedule 06.05.2013    source источник
comment
Это не ошибка iOS - если бы это было, тысячи приложений не работали бы. Почему-то ваши изображения не публикуются.   -  person David H    schedule 06.05.2013
comment
Очевидно проблема в моей программе, но, как видно на скриншоте, пользовательская память очищается правильно (первая диаграмма показывает ограниченное потребление). С другой стороны, мы видим огромный рост грязной памяти. И я действительно не понимаю, в чем может быть проблема. Кстати, я зарегистрировал метод dealloc и увидел, что он был вызван.   -  person ZAN    schedule 07.05.2013
comment
Итак, что показывает треугольник раскрытия для Image_IO? То есть выставьте список и обновите свой вопрос.   -  person David H    schedule 07.05.2013
comment
Добавлен новый скриншот. Кстати, я попробовал протестировать подозрительный компонент (коллаж с несколькими картинками) в тестовом приложении - создал и удалил 1000 по кругу, но утечки не обнаружил.   -  person ZAN    schedule 07.05.2013
comment
@ZAN привет .. у меня такая же проблема. память приложения постоянно увеличивается и через некоторое время вылетает. пожалуйста, посмотрите на это в моем коде stackoverflow.com/questions/29017579/, пожалуйста, помогите мне. где я ошибаюсь.   -  person Hitarth    schedule 13.03.2015


Ответы (2)


Помещая это здесь как слишком большое для комментария, просто несколько идей:

1) один из способов сохранить объекты по ошибке - иметь объекты в представлениях, которые скрываются, но не удаляются из их супервизора (и, таким образом, остаются сохраненными)

2) если вы что-то делаете с UIImageView и т.д. в любом потоке, а не в основном потоке, могут произойти плохие вещи (например, это)

3) скопируйте свой проект, чтобы вы могли беспрепятственно возиться с ним, и попробуйте кучу вещей:

  • вместо нескольких изображений всегда загружайте одно и то же изображение, но оставляйте другие части кода такими, какие они есть - что-то изменится?

  • В любых создаваемых вами подклассах, которые будут хранить / сохранять изображения, поместите сообщение журнала в dealloc, чтобы увидеть, действительно ли эти объекты освобождаются.

  • подкласс UIImageView, используйте его для изображений и зарегистрируйте освобождение

  • подкласс UIImage, используйте его для этих изображений, зарегистрируйте освобождение

4) Мне трудно поверить, что в imageio есть дефект, который может сделать это, но вы могли бы переключиться на использование imageWithData и загрузить данные самостоятельно. Используйте флаг F_NOCACHE, когда вы на самом деле читаете данные - на SO есть другой код о том, как это сделать, вы можете искать по нему (я ответил на вопрос по этому поводу).

Если вы сможете создать демонстрационный проект с этим дефектом, отладить его будет намного проще, чем просто угадать, что делать. Регистрация класса, который был освобожден, имеет большое значение, поскольку вы сразу увидите, что не освобождается, а затем лучше сосредоточитесь на проблеме.

person David H    schedule 07.05.2013
comment
Проблема решена. Утечка экземпляров UIImage. Раньше я создавал их, используя [UIImage imageWithContentOfFile: path], и пул автозапуска не выпускал их вовремя. После переключения на явное сохранение / освобождение проблема исчезла. Самым сложным для меня было то, что инструмент выделения не показывал дополнительного потребления памяти. Насколько я понимаю, UIImage не содержит растровых данных, а только ссылку на ImageIO, который находился в грязном пространстве памяти. Большое спасибо Дэвиду, он заверил меня, что это всего лишь проблема с сохранением, поэтому, наконец, я нашел просочившиеся экземпляры. - person ZAN; 07.05.2013
comment
В настоящее время я столкнулся с той же проблемой. Однако мое приложение - это не галерея изображений, а простой UIWebView. Это приводит к чрезмерному увеличению грязной памяти, в основном из-за данных Image IO и Performance Tool. Вы знаете, с чего мне начать копать? - person Nikhil J Joshi; 08.12.2013
comment
@NikhilJJoshi, поэтому выпускайте веб-просмотр и время от времени заменяйте его новым. Это все, о чем я могу думать. Наверное, слишком долго держится за прошлые страницы. Возможно, вы можете установить политику кэширования или удалить старые страницы - у вас нет большого опыта работы с этим классом. - person David H; 08.12.2013
comment
@DavidH, у меня такая же проблема. память приложения постоянно увеличивается и через некоторое время вылетает. пожалуйста, посмотрите на мой код stackoverflow.com/questions/29017579/ ... пожалуйста, помогите мне. где я ошибаюсь. - person Hitarth; 13.03.2015

В дополнение к ответу Дэвида Х я бы порекомендовал всем, кто сталкивается с этой проблемой, также проверить, вызываются ли деинициализаторы вашего контроллера представления, модели, UIDocument (если вы их используете), когда они не нужны.

Если вы не освободите эти классы должным образом, и они содержат данные изображения / VDO / содержимого, которые UIKit ссылается на него, то это может привести к этому сценарию, когда вы видите, что использование памяти VM: ImageIO всегда увеличивается, но при этом вы не видите утечки памяти, когда вы используйте инструменты, так как это содержимое теперь хранится внутри UIKit.

Я тоже столкнулся с этой проблемой дважды, и в моем случае оказалось, что деинициализатор моей модели никогда не вызывался из-за несвязанных проблем. Устраняя эти несвязанные проблемы и убедившись, что моя Модель освобождена, этот VM: ImageIO непрерывный рост исчез.

введите описание изображения здесь

person HuaTham    schedule 14.01.2018