Как снизить объем памяти IOKit резервов при запуске процесса?
Я разработчик, работающий на очень большом 32-разрядном приложении с интенсивной памятью. Запуск виртуального адресного пространства (памяти) является проблемой для нас. Во время моего исследования некоторых недавних выпусков я заметил большой кусок памяти, зарезервированный IOKit (512 МБ). Эта память не выделена, а зарезервирована. Дальнейшее исследование показало, что большинство приложений (Safari, iTunes и т.д.) Также резервируют этот кусок памяти. Кажется, он остался нераспределенным. Я использую vmmap для тестирования. Например, вот приложение Cocoa, созданное с помощью XCode, используя шаблон по умолчанию:
REGION TYPE VIRTUAL
=========== =======
CG backing stores 1008K
CG image 4K
CG raster data 64K
CG shared images 2252K
Carbon 7264K
CoreGraphics 16K
IOKit (reserved) 512.0M reserved VM address space (unallocated)
MALLOC 59.0M see MALLOC ZONE table below
MALLOC guard page 48K
MALLOC metadata 348K
Memory tag=242 12K
STACK GUARD 56.0M
Stack 8712K
VM_ALLOCATE 16.2M
__DATA 8296K
__IMAGE 1240K
__LINKEDIT 31.5M
__TEXT 76.7M
__UNICODE 536K
mapped file 27.4M
shared memory 1320K
=========== =======
TOTAL 809.2M
TOTAL, minus reserved VM space 297.2M
Есть ли что-нибудь, что я могу сделать, чтобы уменьшить или устранить этот пул памяти? Наше приложение действительно может использовать этот 512 МБ!!!
EDIT: Я сделал еще несколько исследований, и кажется, что этот кусок памяти - это фреймбуфер видеокарты, отображаемый в пространстве пользователя. Поэтому я думаю, что более точный вопрос заключается в том, что в любом случае ограничить фреймбуфер, занимающий такую большую часть виртуального адресного пространства пользовательского режима?
РЕДАКТИРОВАТЬ: Проделал ли еще какое-то дополнительное тестирование и нашел ключ, который нужно изменить, это IOFBMemorySize. Как показано, если вы выполните эту команду:
ioreg -l | grep IOFBMemorySize
Или вы можете увидеть его в IORegistryExplorer. Однако я не смог изменить это значение. Я попытался добавить его в Info.plist для ATIFramebuffer.kext, ничего хорошего. Я попытался написать программу, которая вызывает IOConnectSetCFProperty, но она вернула kIOReturnUnsupported.
EDIT: после дополнительных исследований кажется, что этот ключ IOFBMemorySize скорее всего доступен только для чтения, просто сообщив объем доступной памяти на видеокарте. В Configuration.plist для CoreGraphics наблюдались интересные значения, но ни один из них, похоже, не влиял на распределение памяти (даже после перезагрузки).
Ответы
Ответ 1
Я думаю, вы смотрите на это неправильно.
A) IOKit не захватывает 512 МБ памяти для буфера кадров.
B) он указывает в таблице, что вы разместили reserved VM address space (unallocated)
, так что это, вероятно, память диска, которая отображается как пространство виртуальной памяти.
C), если в вашем запущенном приложении заканчивается нехватка памяти, вам необходимо структурировать ее по-разному, изучить распределения и утечки, а при необходимости выполнить кеширование и ленивую выборку.
Ответ 2
По правде говоря, это не ответ на ваш вопрос, а предложение о том, как продолжить...
вы пишете, что работаете над очень большим 32-битным приложением, так что, возможно, настало время переосмыслить вашу исполняемую архитектуру и отделить очень большое приложение от нескольких процессов. возможно, вы хотите упаковать 32-битный конкретный (QT?) код в одно приложение (будь то фоновый процесс или графический интерфейс...), а затем помещать больше памяти и обрабатывать ориентированные биты в вторичное (64-битное?) приложение. есть много разновидностей межпроцессного общения на выбор, и ваше приложение может потенциально извлечь выгоду из более параллельной архитектуры.
просто идея... удачи!
| К <
Ответ 3
а. Вы пытались запустить это на более слабой графической карте? Так может быть выделено только 128fb?
Настройки оборудования для видеокарты?
б. Используйте ввод кода для отмены выделения памяти...
Предполагая, что это ваше личное приложение, которое не использует фреймбоут и т.д. и т.д.
Очевидно, это не одно изменение строки, но вы можете изменить код для выделения меньшего буфера или не выполнить выделение или разрешить выделение, а затем освободить его (и отменить это во время выключения программы) и т.д. И т.д.
Я уверен, что это можно сделать стабильным образом