В приложении iOS не хватает памяти без предупреждения о нехватке памяти - PullRequest
12 голосов
/ 24 марта 2012

У меня есть приложение, в которое я недавно внес некоторые изменения, и я тестировал эти изменения. Приложение отлично работает на каждом iPad, на котором я его тестировал (iOS 4 и iOS 5). После загрузки нескольких (более 50) изображений с большим количеством изображений в мое приложение я получаю предупреждение о нехватке памяти, и мои методы viewDidUnload вызывают, и они правильно обнуляют все свои элементы управления, и мой кэш изображений в памяти очищается, и приложение продолжает просто хорошо.

Однако на iPhone 4 и iPhone4s (iOS 5.0.1 и iOS 5.1) я столкнулся с проблемой, когда у моего приложения не хватает памяти без предупреждения о недостаточном объеме памяти. После загрузки нескольких разных представлений в конечном итоге появится новое представление, которое будет в основном пустым, и на консоли я вижу сообщения о выделении памяти, и весь телефон перестает отвечать на запросы и иногда убивает мое приложение.

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

Этот существующий вопрос похож:

Приложение IOS убито из-за недостатка памяти, но не получено предупреждение о памяти

и этот ответ предполагает, что это может произойти, если я застряну в цикле, но я почти уверен, что мой код не застрял ни в одном цикле. Я просто переключаюсь из одного представления в другое в UINavigationController, и в каждом представлении загружается несколько изображений. Кроме того, другой вопрос специально возникал на iPad, где я не вижу эту проблему на iPad, только на iPhone.

Кстати, я попытался зарегистрироваться для уведомления о нехватке памяти через NotificationCenter, и у меня в делегате приложения есть метод applicationDidReceiveMemoryWarning, и у него есть точки останова в обоих случаях, и ни один из них не вызывается. Кроме того, в консоли отладчика также не отображается сообщение о нехватке памяти.

Есть идеи о том, что может происходить?


Добавлено 26.03.2012:

Интересно, что когда я тестировал свое приложение на новом iPad, у него возникла та же проблема, что и на iPhone 4 и 4, где уведомление о нехватке памяти не принимается. Поэтому мне интересно, вижу ли я ту же проблему, что и этот другой поток:

Новый iPad: предупреждения о нехватке памяти появляются?

но разработчик в этом потоке тестирует приложение только для iPad и поэтому не тестирует и не находит эту же проблему на любых iPhone.

Я провел обширное тестирование и у меня есть список устройств, где я правильно получил предупреждение о нехватке памяти, и устройств, где я его никогда не получал. Пока что я вижу проблему только на iOS5 или выше, однако на iPad1 с iOS 5.0 и 5.1 я не вижу проблемы, так что это проблема не только на всех устройствах на iOS 5.

Вот этот список:

Правильное предупреждение о нехватке памяти

iPad1 4.2.1
iPad1 5.0
iPad1 5.1
iPad2 4.3.3
iPhone3G 4.2.1
iPod 3G 4.3.3
iPhone4 4.3.3

Нет предупреждения о недостаточном объеме памяти

iPhone4 5.1
iPhone4s 5.0.1
iPad3 5.1

Ответы [ 4 ]

2 голосов
/ 29 марта 2012

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

Вы не говорите, где расположены все эти изображения - надеюсь, вы записываете их в файловую систему, а затем загружаете их в представления с помощью [UIImage imageWithContentsOfFile] (или, если используете CGImageRefs, затем используете CGImageSourceCreateWithURL). Чего вы хотите избежать, так это хранить изображения в памяти (без подкачки в iOS!).

в моем случае у меня была некоторая память mmap для хранения изображений, я даже распечатал память (которая синхронизирует ее с файловой системой), но поскольку синхронизация занимает так много времени, меня «заряжают» за эту несинхронизированную память. По сути, я вызывал fcntl (fd, F_FULLSYNC) для каждого из этих файлов, чтобы система сбрасывала каждый блок перед тем, как продолжить.

1 голос
/ 27 июня 2012

Я работаю над приложением с множеством больших изображений на iPad 3.

Если я установлю iOS 5.0 в качестве цели развертывания, applicationDidReceiveMemoryWarning не будет вызван, если приложение потребляет слишком много памяти и приложение вылетает.

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

Основная проблема заключается в том, что я использую UIImage imageNamed: для загрузки своих изображений, если ваши изображения широко используются, вместо этого UIImage imageWithContentsOfFile, чтобы они не кэшировались (что является проблемой, если размер @ 2x очень большой).

Обратите внимание, что если я отображаю много изображений очень быстро, applicationDidReceiveMemoryWarning не вызывается вовремя в iOS 5.1, и у меня происходит сбой!

0 голосов
/ 16 апреля 2012

Я нашел именно такое поведение на iPad 3 под управлением iOS 5.1.applicationDidReceiveMemoryWarning не вызывается, как и NSNotifications для UIApplicationDidReceiveMemoryWarningNotification.Я также тестировал точно такой же код на некоторых других устройствах, поэтому вы можете добавить их в свой список:

Правильное предупреждение о нехватке памяти

iPad 2 5.0.1
iPad 2 4.3.5
iPhone 3GS 5.0.1

Нет предупреждения о нехватке памяти

iPad 3 5.1

Шаблон может быть следующим: устройства iOS с 512 МБ или 1 ГБ памяти с 5.0.1 - 5.1.

Я не делаю никакой тяжелой обработки UIImage в этом приложении.Похоже, что поведение в ОС изменилось - либо она намеренно убивает приложения более агрессивно (например, пытается быть умнее в отношении уничтожения приложений, которые выглядят так, как будто они слишком обременительно используют память), либо уведомления о нехватке памяти просто нарушаются.

0 голосов
/ 24 марта 2012

Можете ли вы попробовать запустить в Инструментах для инструмента "Time Profiler"? Он скажет вам, связаны ли вы с процессором в другом потоке (хотя, если вы не создадите их самостоятельно, я буду удивлен, если это так). Также хорошо использовать инструмент «Распределение», если на нем нет дымящихся пистолетов.

...