Попередження про пам'ять ОС iPhone. Що означають різні рівні?


85

Щодо чорного мистецтва управління пам’яттю на пристроях з ОС iPhone: що означають різні рівні попередження про пам’ять. 1 рівень? 2 рівень? Циферблат переходить на 11?

Контекст: Після тривалого періоду стрес-тестування пам’яті, включаючи запуск програми iPad для програвання музичного програвача iPod, я схильний ігнорувати випадкові, але рідкісні попередження про пам’ять, які отримую. Мій додаток ніколи не виходить з ладу. Ніколи. Мій додаток є вільним. Ну, ну, попередження мем просто не мають значення.

Дякую,
Даг

Відповіді:


98

В основному попередження означають, що в пристрої мало пам'яті, і що, "Якби ви могли звільнити трохи пам'яті, якою ви не активно користуєтесь, це було б набрякло! ". Якщо ваше керування пам’яттю є жорстким, і у вас немає об’єктів, які практично можна було б відкинути, просто передайте повідомлення та проігноруйте його.


25
LOL "Якби ви могли звільнити трохи пам'яті, якою ви не користуєтесь активно, це було б здорово!" Безцінне ;-)
Вітаю

15
Ви схожий на скрипленого ветерана танцю пам’яті в стилі wack-a-mol на iPhone OS.
дугла

193

Попередження про рівень пам'яті реєструються SpringBoard. Як розробник програми вам не потрібно про це дбати. Досить просто відповісти на -{application}didReceiveMemoryWarning.


Є 4 рівні попереджень (від 0 до 3). Вони встановлюються із засобу перегляду пам'яті ядра та можуть бути отримані за допомогою не надто загальнодоступної функціїOSMemoryNotificationCurrentLevel() .

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

Як спрацьовують рівні, не задокументовано. SpringBoard налаштований на наступне на кожному рівні пам'яті:

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

Вбивством активного додатка (jetsam) не займається SpringBoard, а launchd.


Дякую за це. Це було кидання між вами та коміком Вілліхамом у цьому питанні. Гумор перемагає. Ура.
дугла

Привіт, у мене така ж проблема. Після постійного запуску програми більше 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).

Щодо опису попередження про рівень пам’яті, відповідь @ KennyTM є чудовою.

Я хочу додати кілька супутніх моментів, які можуть допомогти ПМ та іншим.


Що робити, коли з’являється попередження про рівень пам’яті?

Отримавши будь-яке з цих попереджень, ваш метод обробника повинен відповісти, негайно звільнивши будь-яку непотрібну пам’ять. Наприклад, поведінка класу 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.