Как уменьшить объем памяти, которую 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 МБ!!!

РЕДАКТИРОВАТЬ: я провел еще несколько исследований, и кажется, что этот кусок памяти - это буфер кадра видеокарты, отображаемый в пользовательское пространство. Поэтому я думаю, что более точный вопрос заключается в том, можно ли каким-либо образом ограничить фреймбуфер, занимающий такую ​​большую часть виртуального адресного пространства пользовательского режима?

РЕДАКТИРОВАТЬ: Провел дополнительное тестирование и обнаружил, что ключ, который необходимо изменить, - это IOFBMemorySize. Как показано, если вы выполните эту команду:

ioreg -l | grep IOFBMemorySize

Или вы можете увидеть это в IORegistryExplorer. Однако мне не удалось изменить это значение. Я попытался добавить его в Info.plist для ATIFramebuffer.kext, но ничего хорошего. Я попытался написать программу, которая вызывает IOConnectSetCFProperty, но она вернула kIOReturnUnsupported.

РЕДАКТИРОВАТЬ: После дополнительных исследований кажется, что этот ключ IOFBMemorySize, вероятно, предназначен только для чтения, просто сообщая об объеме памяти, доступной на видеокарте. В файле Configuration.plist для CoreGraphics оказалось несколько интересных значений, но ни одно из них не повлияло на выделение памяти (даже после перезагрузки).


person pj4533    schedule 27.06.2011    source источник


Ответы (3)


Я думаю, вы смотрите на это неправильно.

A) IOKit не занимает 512 МБ памяти для буфера кадров.

B) в таблице указано, что вы опубликовали это reserved VM address space (unallocated), так что, вероятно, это память диска, которая отображается как пространство виртуальной памяти.

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

person Grady Player    schedule 03.07.2011
comment
A) он захватывает 512 МБ виртуального адресного пространства, исходя из размера буфера кадра. Б) да виртуальное адресное пространство. Из которых на 32битное приложение приходится 4гб. C) Не совсем отвечает на вопрос. - person pj4533; 04.07.2011
comment
Неважно, сколько адресов доступно, важно, сколько памяти доступно, только потому, что вы можете считать до числа, не означает, что у вас есть столько битов. - person Grady Player; 04.07.2011
comment
Мммм .... не уверен, что понимаю, что вы говорите, но абсолютно важно, сколько адресов доступно (32-битные против 64-битных). Дело в том, что 32-битные задачи имеют (примерно) 4 ГБ виртуального адресного пространства. Как только это используется, выделение памяти терпит неудачу. IOKit резервирует 512 МБ виртуального адресного пространства для фреймбуфера видеокарты, и я хочу знать, как уменьшить его до меньшего размера. - person pj4533; 05.07.2011
comment
Почему бы просто не скомпилировать приложение как 64-битное? Все, начиная с 10.5, поддерживает его, и это увеличивает вашу виртуальную память до 64 гигабайт. developer.apple.com/library/mac /#documentation/Какао/Концептуальное/ - person synthesizerpatel; 07.07.2011
comment
компиляция как 64-битная не всегда вариант. Например, Quicktime не поддерживает 64-битную версию... - person kent; 07.07.2011
comment
Я не совсем уверен, что вы хотите сделать, но изменение системы вряд ли будет ответом, вы можете попробовать использовать mmap и выделить по существу другое адресное пространство с расширением физического адреса. Я воспользуюсь этим моментом, чтобы повторить... вам нужно сделать что-то по-другому, кэшировать и получать или где-то оптимизировать. - person Grady Player; 07.07.2011
comment
У меня действительно не так много вариантов, учитывая кодовую базу, с которой я работаю. 512 МБ, которые я вызываю из фреймбуфера, кажутся готовыми для оптимизации, учитывая, что они остаются в зарезервированном состоянии на протяжении всего выполнения приложения. И отображается в каждом процессе в системе. Что касается PAE, разве это не уровень ядра? т. е. ядро ​​OSX уже поддерживает его. PAE — это не технология пользовательского режима, которую я могу использовать в своей задаче, не так ли? - person pj4533; 08.07.2011
comment
это активность ядра, но я думаю, что вы можете использовать void * mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);, чтобы создать новый файл подкачки, затем синхронизировать его, а затем создать новый. Я никогда не делал этого, но я думаю, что это возможно. - person Grady Player; 08.07.2011

по общему признанию, это не ответ на ваш вопрос, а предложение о том, как продолжить...

вы пишете, что работаете над очень большим 32-битным приложением, так что, возможно, сейчас самое время переосмыслить вашу исполняемую архитектуру и разделить очень большое приложение на несколько процессов. возможно, вы хотите упаковать 32-битный код (QT?) в одно приложение (будь то фоновый процесс или управляемый графический интерфейс ...), а затем поместить более интенсивные в памяти и ориентированные на обработку биты во вторичное (64-битное?) приложение. существует множество вариантов межпроцессного взаимодействия, и ваше приложение потенциально может извлечь выгоду из более параллельной архитектуры.

просто идея... удачи!

|K<

person kent    schedule 07.07.2011
comment
спасибо .... и да, 64-битная версия - это долгосрочное решение этой проблемы. К сожалению, нам нужно поддерживать 32-битную ветку нашего приложения в течение некоторого времени из-за потребностей клиентов. - person pj4533; 07.07.2011
comment
Кроме того, я задавался вопросом, есть ли способ сделать низкоуровневый распределитель памяти вне процесса. Переопределяя malloc моей собственной реализацией, которая использовала IPC для получения памяти из другого (64-битного) процесса. Хотя всегда казалось, что это натянуто (не говоря уже о том, что это сложно реализовать в большой устаревшей кодовой базе). - person pj4533; 07.07.2011

а. Пробовали запускать на более слабой видеокарте? Так может быть будет выделено только 128fb? Аппаратные настройки видеокарты?

б. Используйте инъекцию кода, чтобы отменить выделение памяти...

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

Бьюсь об заклад, это можно сделать стабильным образом

person YAZR    schedule 20.07.2011
comment
Поскольку каждое приложение OSX демонстрирует такое поведение, я попытался изучить процессы на других машинах с другими видеокартами. Да, объем зарезервированной памяти разный. (зарезервировано, но не выделено судя по всему). Я искал аппаратную настройку, ОЧЕНЬ глубоко копался в настройках, но не нашел ничего, что можно было бы установить пользователем. После разговора с Apple об этой проблеме оказалось, что она полностью контролируется видеодрайвером. Полагаю, я мог бы перехватить звонок, но Apple посоветовала этого не делать (очевидно). - person pj4533; 21.07.2011
comment
Хорошо.. это действительно экстремально... но ты кажешься наполовину компетентным, так что - person YAZR; 05.08.2011