Отвечая на доступность оперативной памяти в iOS - PullRequest
9 голосов
/ 07 ноября 2011

У меня игра OpenGL с высокой текстурой, которую я хотел бы настроить в зависимости от того, сколько оперативной памяти имеет устройство.Текстуры с самым высоким разрешением у меня отлично работают на iPhone 4 или iPad2, но более ранние устройства вылетали в середине загрузки текстур.У меня есть версии этих текстур в низком разрешении, но мне нужно знать, когда их использовать.

Моя текущая тактика заключается в обнаружении определенных старых устройств (у 3GS есть экран с низким разрешением; у iPad нет камеры),затем загружайте только текстуры высокого разрешения для IPad2 и выше и iPhone 4 и выше - и я полагаю, что мне нужно что-то сделать для iPod touch.Но я бы предпочел использовать обнаружение функций, а не модели устройств с жестким кодированием, поскольку обнаружение моделей хрупко по отношению к будущим изменениям API и аппаратного обеспечения.

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

Как определить, имеет ли устройство, на котором я работаю, недостаточно ОЗУ для загрузки версий моего высокого разрешениятекстуры?

Делая шаг назад, есть ли какой-нибудь другой адаптивный метод, который я могу использовать, специфичный для памяти текстур OpenGL?

Примечания:

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

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

Ответы [ 4 ]

11 голосов
/ 02 октября 2013

Для получения общего (максимального) физического ОЗУ устройства используйте [NSProcessInfo processInfo].physicalMemory.

См. Документация .

7 голосов
/ 10 ноября 2011

Общее физическое ОЗУ доступно через sysctl(), как описано в в этом сообщении в блоге и реализовано как красивый чистый API здесь (см. Реализацию totalMemory в соответствующем.m file).

Я поднял код блога для удобства и потомства:

#include <sys/sysctl.h>

size_t phys_mem()
{
 int mib[] = { CTL_HW, HW_PHYSMEM };
 size_t mem;
 size_t len = sizeof(mem);
 sysctl(mib, 2, &mem, &len, NULL, 0);
 return mem;
}

Я не знаю, одобрит ли Apple приложение, которое использует в этом sysctl()манера.Это задокументировано, но только для Mac OS X.

2 голосов
/ 09 ноября 2011

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

CGFloat scale = [[UIScreen mainScreen] scale];
if ((scale > 1.0) || (self.view.frame.size.width > 320)) {
        highRes = TRUE;
}

. Пока это работает для всех устройств и должно быть ориентировано на будущее, более новые устройства будут использовать высокое разрешение.Вы также можете сразу рассчитать соотношение сторон (это поможет позже на ipad против iphone)

aspect = self.view.frame.size.width/self.view.frame.size.width

Не загружайте высокое разрешение, сначала это убивает время загрузки ваших приложений, в моем 3G большая часть моего запуска тратится на загрузку (даже текстуры с низким разрешением), просто проверьте это в самом начале и не трогайте материал с высоким разрешением.

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

Для большей оптимизации рассмотрите возможность раскраски мипмапов, чтобы проверить минимальный размер текстуры, который фактически используется (только если вы используете 3D-объекты).

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

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

0 голосов
/ 07 ноября 2011

Насколько я знаю, 3 самые важные вещи, которые можно сделать, -

  1. внедряют - (void)didReceiveMemoryWarning и отвечают, когда iOS отправляет предупреждения 1 и 2.
  2. Код профиля вИнструменты, пытающиеся найти утечки и лучше запоминать оптимальные способы реализации.
  3. Обнаружение типов устройств и, возможно, использование этой информации.
  4. Использование некоторой формы сжатия текстур, например PVRTC, для экономии места.

Я думаю, вы делаете большинство из них.Дело в том, что никто даже не знает точно, сколько RAM устройств iOS имеет.Apple не публикует технические спецификации для устройств iOS.

Кроме того, нельзя предполагать, что только после, скажем, 100 Мб потребления вы получите предупреждение mem.Предупреждения, которые выдает iOS, различаются в зависимости от текущего состояния устройства и запуска других приложений, а также от того, сколько памяти они потребляют.Это становится сложнее.

Я могу предложить 2 раздела для чтения - Рекомендации по работе с данными текстуры и Настройка приложения OpenGL ES

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