Я создаю приложение макета фотокниги. Приложение часто распаковывает изображения JPEG в буферы растровых изображений в памяти. Размер изображений ограничен 100 мегапикселями (в то время как они обычно не превышают 15 мегапикселей).
Иногда выделяются выделения памяти для этих буферов: [[NSMutableData alloc] initWithLength:]
возвращает nil
. Это, похоже, происходит в ситуациях, когда системная свободная физическая память приближается к нулю.
Мое понимание системы виртуальной памяти в Mac OS X заключалось в том, что выделение в 64-битном процессе практически (sic) не может потерпеть неудачу, Есть 16 экзабайт адресного пространства, из которых я пытаюсь выделить максимум 400 мегабайт за раз. Теоретически я мог выделить 40 миллиардов этих буферов, не нажимая жесткого предела доступного адресного пространства. Разумеется, практические ограничения будут препятствовать этому сценарию, поскольку пространство подкачки ограничено размером загрузочного тома. На самом деле я делаю очень мало таких распределений (менее десяти).
То, что я не понимаю, - это тот факт, что распределение выходит из строя, независимо от того, насколько низкая физическая память в данный момент. Я думал, что, пока пространство подкачки пространства слева-памяти не будет терпеть неудачу (поскольку страницы не отображаются в данный момент).
Приложение - сбор мусора.
Edit:
У меня было время немного углубиться в эту проблему, и вот мои выводы:
- Проблема возникает только в процессе сбора мусора.
- Когда выделение из
NSMutableData
выходит из строя, простойmalloc
по-прежнему удается выделить один и тот же объем памяти. - Ошибка всегда возникает, когда общая физическая память приближается к нулю (происходит переключение).
Я предполагаю, что NSData
использует NSAllocateCollectable
для выполнения выделения вместо malloc
при запуске под сборкой мусора.
Мой вывод из всего, что коллекционер не может выделить большие куски памяти, когда физическая память низкая. Что еще раз, я не понимаю.