Понимание потребления памяти на iPhone - PullRequest
35 голосов
/ 12 декабря 2008

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

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

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


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

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


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

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

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

  3. Я неправильно прочитал Руководство по программированию. Ограничение памяти в 24 МБ относится к текстурам и поверхностям, а не ко всему приложению. Фактическая красная линия лежит немного дальше, но я не смог найти никаких точных цифр. По общему мнению, потолок составляет 25–30 МБ.

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

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

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

Ответы [ 5 ]

11 голосов
/ 19 марта 2010

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

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

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

Выдержка:

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

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


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

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

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

3 голосов
/ 16 декабря 2008

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

Где происходит сбой, почему происходит сбой и т. Д.

2 голосов
/ 22 августа 2013

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

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

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

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

2 голосов
/ 14 декабря 2008

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

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

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

0 голосов
/ 12 декабря 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...