Предупреждения относительно памяти iPhone OS. Что означают разные уровни?


85

Что касается черного искусства управления памятью на устройствах iPhone OS: что означают разные уровни предупреждения о памяти. 1-й уровень? Уровень 2? Циферблат идет на 11?

Контекст: после продолжительного периода стресс-тестирования памяти, в том числе запуска моего приложения iPad с проигрывателем iPod, я склонен игнорировать случайные, но нечастые предупреждения памяти, которые получаю. Мое приложение никогда не вылетает. Когда-либо. В моем приложении нет утечек. И, ну, мем-предупреждения, похоже, не имеют значения.

Спасибо,
Дуг

Ответы:


98

В основном предупреждения означают, что на устройстве заканчивается память, и что «если бы вы могли освободить память, которую вы не используете активно, это было бы здорово! ». Если у вас жесткое управление памятью и у вас нет объектов, которые можно было бы практически отбросить, просто передайте сообщение и игнорируйте его.


25
LOL "Если бы вы могли освободить немного памяти, которую вы не используете активно, это было бы здорово!" Бесценно ;-) Ура
дугла

15
Вы говорите, как сварливый ветеран танцевальной памяти iPhone OS.
дугла

193

Предупреждения об уровне памяти регистрируются SpringBoard. Как разработчику приложения вам не нужно об этом заботиться. Достаточно просто ответить -{application}didReceiveMemoryWarning.


Есть 4 уровня предупреждений (от 0 до 3). Они устанавливаются наблюдателем за памятью ядра и могут быть получены с помощью функции not-so-publicOSMemoryNotificationCurrentLevel() .

typedef enum {
    OSMemoryNotificationLevelAny      = -1,
    OSMemoryNotificationLevelNormal   =  0,
    OSMemoryNotificationLevelWarning  =  1,
    OSMemoryNotificationLevelUrgent   =  2,
    OSMemoryNotificationLevelCritical =  3
} OSMemoryNotificationLevel;

Как срабатывают уровни, не задокументировано. SpringBoard настроен на выполнение следующих действий на каждом уровне памяти:

  1. Предупреждение (ненормально) - перезапуск или отложенный автоматический перезапуск второстепенных фоновых приложений, например почты.
  2. Срочно - Закройте все фоновые приложения, например Safari и iPod.
  3. Критично и не только - ядро ​​возьмет на себя управление, возможно, отключение SpringBoard или даже перезагрузка.

Удаление активного приложения (jetsam) не обрабатывается SpringBoard, но launchd.


Спасибо за это. Между вами и комиком Уильямом Уильямсом была битва по этому вопросу. Юмор побеждает. Ура.
dugla

Привет, у меня такая же проблема. После непрерывного запуска приложения более 5 раз я получаю предупреждение о получении памяти. Уровень = 1 20 раз, но приложение не вылетает. Но когда я получаю это сообщение, получено предупреждение о памяти. Уровень = 2 мое приложение вылетает. Уровень 2 появляется после того, как Уровень 1 появляется почти 20 раз. Как сделать, чтобы приложение не падало. Спасибо
srikanth rongali

1
@Kenny: Меньше памяти означает, сколько мы можем использовать максимум. Сколько у нас может быть живых байтов. В моем аварийном журнале есть вот это. Свободных страниц: 371 Связанных страниц: 12192 Очищаемых страниц: 0 Самый большой процесс: DTMobileIS Что это значит? Где мне позаботиться? Спасибо.
srikanth rongali

9
@srik: Тебе лучше задать новый вопрос .
kennytm

@kennytm: возможно ли это с ios8? Я видел, что функция определена в libsystem_c.dylib. Было бы здорово, если бы я мог воспользоваться им. Спасибо
focs

12

Из OSMemoryNotification.h ,

/*
** Threshold values for notifications
*/

typedef enum {
    OSMemoryNotificationLevelAny      = -1,
    OSMemoryNotificationLevelNormal   =  0,
    OSMemoryNotificationLevelWarning  =  1,
    OSMemoryNotificationLevelUrgent   =  2,
    OSMemoryNotificationLevelCritical =  3
} OSMemoryNotificationLevel;

всего 5 уровней предупреждения о памяти (-1,3).

Что касается описания предупреждения об уровне памяти, ответ @Kenny TM отличный.

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


Что делать при появлении предупреждения об уровне памяти?

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


Как увидеть предупреждение об уровне памяти?

Из http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/PerformanceTuning/PerformanceTuning.html.

Когда система отправляет вашему приложению предупреждение о нехватке памяти, немедленно реагируйте. iOS уведомляет все запущенные приложения, когда объем свободной памяти опускается ниже безопасного порога. (Он не уведомляет приостановленные приложения.) Если ваше приложение получает это предупреждение, оно должно освободить как можно больше памяти. Лучший способ сделать это - удалить сильные ссылки на кеши, объекты изображений и другие объекты данных, которые можно воссоздать позже.

UIKit предоставляет несколько способов получения предупреждений о нехватке памяти, включая следующие:

  • Реализуйте метод applicationDidReceiveMemoryWarning: делегата приложения.
  • Переопределите метод didReceiveMemoryWarning в пользовательском подклассе UIViewController.
  • Зарегистрируйтесь, чтобы получить уведомление UIApplicationDidReceiveMemoryWarningNotificationnotification.

Как уменьшить объем памяти вашего приложения?

  • Устранение утечек памяти.
  • Делайте файлы ресурсов как можно меньше.
  • Используйте Core Data или SQLite для больших наборов данных.
  • Загружайте ресурсы лениво.
  • Создайте свою программу, используя опцию Thumb.

Подробности на http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/PerformanceTuning/PerformanceTuning.html.


Как разумно распределить память?

  • Сократите использование автоматически выпущенных объектов : с автоматическим подсчетом ссылок (ARC) лучше выделить / инициализировать объекты и позволить компилятору освободить их для вас в подходящее время. Это верно даже для временных объектов, которые в прошлом вы могли автоматически освобождать, чтобы предотвратить их выход за пределы области действия текущего метода.
  • Ограничение размера ресурсов : избегайте загрузки большого файла ресурсов, если подойдет и меньший. Вместо изображения с высоким разрешением используйте изображение, размер которого соответствует устройствам на базе iOS. Если вам необходимо использовать большие файлы ресурсов, найдите способы загрузить только ту часть файла, которая вам нужна в любой момент времени. Например, вместо того, чтобы загружать весь файл в память, используйте функции mmap и munmap для отображения частей файла в память и из нее. Для получения дополнительной информации о отображении файлов в памяти.
  • Избегайте неограниченных наборов проблем : для вычисления неограниченных наборов проблем может потребоваться произвольно большой объем данных. Если для набора требуется больше памяти, чем доступно, ваше приложение может не выполнить вычисления. Ваши приложения должны по возможности избегать таких наборов и работать над проблемами с известными ограничениями памяти.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.