Подтвердить что ты не робот

Понимание потребления памяти на iPhone

Я работаю над 2D-игрой iPhone с использованием OpenGL ES, и я продолжаю бить ограничение на 24 Мб памяти - мое приложение продолжает сбой с кодом ошибки 101. Я очень старался найти, где находится память, но цифры в инструментах все еще намного больше, чем я ожидал.

Я запустил приложение с помощью инструментов Memory Monitor, Object Alloc, Leaks и OpenGL ES. Когда приложение загружается, свободная физическая память падает с 37 МБ до 23 МБ, объект Alloc занимает около 7 МБ, у Leaks - два или три утечки в несколько байтов, размер объекта Gart - около 5 МБ, а Memory Monitor - приложение занимает около 14 МБ реальной памяти. Я озадачен тем, как происходит память - когда я копаю в Object Allocations, большая часть памяти находится в текстурах, точно так же, как я ожидал бы. Но и мой собственный счетчик распределения текстур, и размер объекта Gart согласны с тем, что текстуры должны занимать около 5 МБ.

Я не знаю, как выделить что-то еще, что стоит упомянуть, и Object Alloc соглашается. Куда идет память? (Я был бы рад предоставить более подробную информацию, если этого недостаточно.)


Обновление: я действительно пытался найти, где я мог бы выделить столько памяти, но без каких-либо результатов. Меня отличает разница между распределением объектов (~ 7 МБ) и использованием реальной памяти, как показано в Monitor Memory (~ 14 МБ). Даже если бы были огромные утечки или огромные куски памяти, о которых я забыл, они должны появиться в Object Allocations, не так ли?

Я уже пробовал обычный подозреваемый, т.е. UIImage с его кэшированием, но это не помогло. Есть ли способ отслеживать использование памяти "стиль отладчика", по очереди, наблюдая, как каждый оператор влияет на использование памяти?


Что я нашел до сих пор:

  • Я использую столько памяти. Измерять потребление реальной памяти непросто, но после большого подсчета я думаю, что потребление памяти действительно велико. Моя ошибка.

  • Я не нашел простого способа измерения используемой памяти. Номера монитора памяти точны (это цифры, которые действительно имеют значение), но монитор памяти не может указать, где именно находится память. Инструмент Object Alloc почти бесполезен для отслеживания использования реальной памяти. Когда я создаю текстуру, выделенный счетчик памяти некоторое время поднимается (чтение текстуры в память), затем падает (передача данных текстуры в OpenGL, освобождение). Это нормально, но это не всегда происходит - иногда использование памяти остается высоким даже после того, как текстура была передана в OpenGL и освобождена от "моей" памяти. Это означает, что общий объем памяти, выделенный как показано инструментом Object Alloc, меньше, чем реальное общее потребление памяти, но больше реального потребления минус текстуры (real – textures < object alloc < real). Идите.

  • Я неправильно прочитал Руководство по программированию. Предел памяти 24 МБ относится к текстурам и поверхностям, а не к целому приложению. Фактическая красная линия лежит немного дальше, но я не мог найти никаких жестких цифр. Консенсус в том, что 25-30 МБ - это потолок.

  • Когда система становится коротким в памяти, она начинает посылать предупреждение о памяти. У меня почти ничего не освобождает, но другие приложения освобождают память обратно в систему, особенно Safari (которая, похоже, кэширует веб-сайты). Когда свободная память, как показано на мониторе памяти, равна нулю, система начинает убивать.

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

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

4b9b3361

Ответ 1

Я очень сомневаюсь, что это ошибка в Инструментах.

Сначала прочитайте это сообщение блога Джеффа Ламарче о текстурах openGL:

  • имеет простой пример загрузки текстуры, не вызывая утечек.
  • дает представление о том, как "маленький" изображения, получить после их загрузки в openGL, на самом деле использовать "много" памяти

Выдержки:

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

Во-вторых, можно отлаживать текстурную память с помощью инструментов. Существуют две конфигурации профилирования: OpenGL ES Analyzer и OpenGL ES Driver. Вам нужно будет запустить их на устройстве, так как имитатор не использует OpenGL. Просто выберите Product- > Profile from XCode и найдите эти профили после запуска инструментов.


Вооруженный этим знанием, вот что я буду делать:

  • Убедитесь, что вы не утечка памяти - это, очевидно, вызовет эту проблему.
  • Убедитесь, что вы не доступ к автореализованной памяти - общая причина сбоев.
  • Создайте отдельное тестовое приложение и поиграйте с загрузкой текстур по отдельности (и в комбинации), чтобы выяснить, какая именно текстура (или их комбинация) вызывает проблему.

ОБНОВЛЕНИЕ:. Подумав о вашем вопросе, я читал Руководство по программированию Apple OpenGL ES, и оно имеет очень хорошую информацию. Очень рекомендуется!

Ответ 2

Один из способов - начать комментирование кода и проверить, не исчезла ли ошибка. Да, это утомительно и элементарно, но это может помочь, если вы знаете, где была ошибка.

Где он сбой, почему он сбой и т.д.

Ответ 3

Hrmm, это не так много деталей, но если утечки не показывают, где находятся утечки, есть два важных варианта:

[i] Утечки пропустили утечку [ii] Память фактически не просачивается.

исправление [i] довольно сложно, но, как сказал Эрик Альберт, подача отчета об ошибке с Apple поможет. [ii] означает, что память, которую вы используете, все еще доступна где-то, но, возможно, вы забыли об этом. Разве какие-то списки растут, не выкидывая старые записи? Являются ли какие-либо буферы realloc() ed много?

Ответ 4

Для тех, кто видит это после 2012 года:

Память, действительно загруженная в физическую память устройства, - это резидентная память в инструменте отслеживания VM.

Инструмент распределения только отмечает память, созданную malloc/[NSObject alloc], и некоторый фрейм-буфер, например, растровое изображение с декомпрессированным изображением не входит в Инструмент распределения, но он всегда занимает большую часть вашей памяти.

Пожалуйста, смотрите WWDC 2012 Сессия 242 Производительность приложений iOS: Память для получения информации от Apple.

Ответ 5

Это не поможет вам, но если вы обнаружите, что инструменты памяти не предоставляют всех необходимых вам данных, пожалуйста, сообщите об ошибке на странице bugreport.apple.com. Приложите копию своего приложения и описание того, как инструменты не соответствуют вашему анализу, и Apple увидит, могут ли они улучшить инструменты. Спасибо!