Максимальный объем памяти ios app
Я работаю над игрой ios, нацеленной как минимум на 3gs. Мы используем HD-ресурсы для устройств отображения сетчатки (iphone 4, ipod touch 4-го поколения).
Память мудрая, Ipod Touch 4-го поколения, по-видимому, является самым ограничивающим устройством для нас, поскольку у него одинаковое количество оперативной памяти (256 по сравнению с Iphone 4 512) как 3gs, но мы используем на нем HD-ресурсы. Приложение, используемое для сбоя при попытке загрузить 100-110 МБ оперативной памяти, но теперь, когда мы до 70 МБ, у нас никогда не было сбоя загрузки.
После многого поиска вокруг, кажется, нет официального жесткого ограничения, так как мы должны знать, какой бюджет памяти использовать, чтобы быть в безопасности? Мы хотим, чтобы дать художникам бюджет, который они могут использовать без проблем памяти для каждой карты.
Ответы
Ответ 1
Я думаю, что вы ответили на свой вопрос: постарайтесь не превышать лимит в 70 Мб, однако это действительно зависит от многих вещей: какая версия iOS вы используете (не SDK), сколько приложений работает в фоновом режиме, какую именно память вы используете и т.д.
Просто избегайте мгновенных всплесков памяти (например, вы используете 40 Мб ОЗУ, а затем выделяете 80 Мб больше для небольшого вычисления). В этом случае iOS немедленно убьет ваше приложение.
Вы также должны учитывать ленивую загрузку активов (загружать их только тогда, когда вам действительно нужно, а не заранее).
Ответ 2
Результаты тестирования с помощью утилиты Split (ссылка в его ответе):
устройство: (сумма сбоя/общая сумма/процент от общего количества)
- iPad1:127MB/256MB/49%
- iPad2: 275MB/512MB/53%
- iPad3: 645 МБ /1024 МБ /62%
- iPad4: 585MB/1024MB/57% (iOS 8.1)
- iPad Mini 1st Generation: 297MB/512MB/58%
- iPad Mini retina: 696MB/1024MB/68% (iOS 7.1)
- iPad Air: 697MB/1024MB/68%
- iPad Air 2: 1383MB/2048MB/68% (iOS 10.2.1)
- iPad Pro 9.7 ": 1395MB/1971MB/71% (iOS 10.0.2 (14A456))
- iPad Pro 10.5 ": 3057/4000/76% (iOS 11 beta4)
- iPad Pro 12,9 "(2015): 3058/3999/76% (iOS 11.2.1)
- iPad Pro 12,9 "(2017): 3057/3974/77% (iOS 11 beta4)
- iPod touch 4-го поколения: 130 МБ /256 МБ /51% (iOS 6.1.1)
- iPod touch 5-го поколения: 286 МБ /512 МБ /56% (iOS 7.0)
- iPhone4: 325MB/512MB/63%
- iPhone4s: 286MB/512MB/56%
- iPhone5: 645 МБ /1024 МБ /62%
- iPhone5s: 646MB/1024MB/63%
- iPhone6: 645MB/1024MB/62% (iOS 8.x)
- iPhone6+: 645 МБ /1024 МБ /62% (iOS 8.x)
- iPhone6s: 1396MB/2048MB/68% (iOS 9.2)
- iPhone6s+: 1392 МБ /2048 МБ /68% (iOS 10.2.1)
- iPhoneSE: 1395MB/2048MB/69% (iOS 9.3)
- iPhone7: 1395/2048MB/68% (iOS 10.2)
- iPhone7+: 2040MB/3072MB/66% (iOS 10.2.1)
- iPhone X: 1392/2785/50% (iOS 11.2.1)
Ответ 3
Я создал небольшую утилиту, которая пытается выделить как можно больше памяти для сбоя, и она записывает, когда произошли сбои памяти и сбои. Это помогает узнать, какой бюджет памяти для любого устройства iOS.
https://github.com/Split82/iOSMemoryBudgetTest
Ответ 4
В моем приложении пользовательский интерфейс лучше, если используется больше памяти, поэтому я должен решить, действительно ли я должен освободить всю память, которую я могу, в didReceiveMemoryWarning
. Основываясь на ответе Split и Jasper Pol, использование максимально 45% общей памяти устройства является безопасным порогом (спасибо ребятам).
Если кто-то хочет посмотреть мою фактическую реализацию:
#import "mach/mach.h"
- (void)didReceiveMemoryWarning
{
// Remember to call super
[super didReceiveMemoryWarning];
// If we are using more than 45% of the memory, free even important resources,
// because the app might be killed by the OS if we don't
if ([self __getMemoryUsedPer1] > 0.45)
{
// Free important resources here
}
// Free regular unimportant resources always here
}
- (float)__getMemoryUsedPer1
{
struct mach_task_basic_info info;
mach_msg_type_number_t size = sizeof(info);
kern_return_t kerr = task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &size);
if (kerr == KERN_SUCCESS)
{
float used_bytes = info.resident_size;
float total_bytes = [NSProcessInfo processInfo].physicalMemory;
//NSLog(@"Used: %f MB out of %f MB (%f%%)", used_bytes / 1024.0f / 1024.0f, total_bytes / 1024.0f / 1024.0f, used_bytes * 100.0f / total_bytes);
return used_bytes / total_bytes;
}
return 1;
}
Swift (на основе этого ответа):
func __getMemoryUsedPer1() -> Float
{
let MACH_TASK_BASIC_INFO_COUNT = (sizeof(mach_task_basic_info_data_t) / sizeof(natural_t))
let name = mach_task_self_
let flavor = task_flavor_t(MACH_TASK_BASIC_INFO)
var size = mach_msg_type_number_t(MACH_TASK_BASIC_INFO_COUNT)
var infoPointer = UnsafeMutablePointer<mach_task_basic_info>.alloc(1)
let kerr = task_info(name, flavor, UnsafeMutablePointer(infoPointer), &size)
let info = infoPointer.move()
infoPointer.dealloc(1)
if kerr == KERN_SUCCESS
{
var used_bytes: Float = Float(info.resident_size)
var total_bytes: Float = Float(NSProcessInfo.processInfo().physicalMemory)
println("Used: \(used_bytes / 1024.0 / 1024.0) MB out of \(total_bytes / 1024.0 / 1024.0) MB (\(used_bytes * 100.0 / total_bytes)%%)")
return used_bytes / total_bytes
}
return 1
}
Ответ 5
Разбирая SPLITS repo, я построил один, чтобы протестировать память iOS, которая может быть выделена для Today Extension
iOSMemoryBudgetTestForExtension
Ниже приведен результат, который я получил в iPhone 5s
Предупреждение о безопасности при 10 МБ
Приложение разбилось на 12 МБ
Таким образом, Apple просто позволяет всем расширениям работать с полным потенциалом.
Ответ 6
Вы должны смотреть сеанс 147 из видеозаписей WWDC 2010. Это "Расширенная оптимизация производительности на iPhone OS, часть 2".
Существует много хороших советов по оптимизации памяти.
Некоторые из советов:
- Используйте вложенный
NSAutoReleasePool
, чтобы убедиться, что использование вашей памяти не всплывает.
- Используйте
CGImageSource
при создании эскизов больших изображений.
- Отвечайте на предупреждения о низкой памяти.
Ответ 7
- (float)__getMemoryUsedPer1
{
struct mach_task_basic_info info;
mach_msg_type_number_t size = MACH_TASK_BASIC_INFO;
kern_return_t kerr = task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &size);
if (kerr == KERN_SUCCESS)
{
float used_bytes = info.resident_size;
float total_bytes = [NSProcessInfo processInfo].physicalMemory;
//NSLog(@"Used: %f MB out of %f MB (%f%%)", used_bytes / 1024.0f / 1024.0f, total_bytes / 1024.0f / 1024.0f, used_bytes * 100.0f / total_bytes);
return used_bytes / total_bytes;
}
return 1;
}
Если вы используете TASK_BASIC_INFO_COUNT вместо MACH_TASK_BASIC_INFO, вы получите
kerr == KERN_INVALID_ARGUMENT (4)
Ответ 8
Я создал еще один список, отсортировав список Jaspers оперативной памятью (я сделал свои собственные тесты с помощью инструмента Split и исправил некоторые результаты - проверьте мои комментарии в этом потоке).
RAM устройства: диапазон процентов для сбоя
- 256 МБ: 49% - 51%
- 512 МБ: 53% - 63%
- 1024 МБ: 57% - 68%
- 2048 МБ: 68% - 69%
- 3072 МБ: 66%
- 4096 МБ: 77%
Особый случай:
ОЗУ устройства можно легко прочитать:
[NSProcessInfo processInfo].physicalMemory
По моему опыту безопасно использовать 45% для устройств 1 ГБ, 50% для устройств 2/3 ГБ и 55% для устройств 4 ГБ. Процент для macOS может быть немного больше.