Вопрос по memory-management, c++, windows, visual-studio, memory – выделить более 1 ГБ памяти на 32-битной XP

10

Я столкнулся со странной проблемой, мой процесс не может выделить больше, чем кажется, что немного ниже 1 ГиБ. В столбце диспетчера задач Windows «Использование памяти» отображаются значения, близкие к 1 ГБ, когда мое программное обеспечение выдаетbad_alloc исключение. Да, я проверил, что значение, переданное для выделения памяти, является разумным. (нет расы / коррупции, которая бы провалилась). Да, мне нужна вся эта память, и нет никакого способа обойти это. (Это буфер для изображений, который больше не может быть сжат)

Я не пытаюсь выделить всю 1 ГБ памяти за один раз, там несколько выделений около 300 МБ каждый. Это вызовет проблемы? (Я постараюсь выяснить, работает ли более небольшое выделение ресурсов лучше). Есть какой-то переключатель компилятора или что-то еще, что я должен установить, чтобы пройти 1 ГиБ? Я видел, как другие жаловались на ограничение в 2 ГиБ, что было бы хорошо для меня .. Мне просто нужно немного больше :). Я использую VS 2005 с пакетом обновления 1 (SP1), и я запускаю его на 32-битной XP, и это на C ++.

Очевидная вещь, которую стоит попробовать - это гораздо меньшие выделения, например, 1 МБ каждый. Если они работают, вы сталкиваетесь с проблемами фрагментации. Просто попробуйте. Если они не работают, это было бы полезно добавить к вашему вопросу. Roman Starkov
Меня глубоко огорчает, что я ограничен 32-битной ОС. Это просто то, с чем я должен жить сейчас. 0xbaadf00d
У SysInternals есть несколько инструментов, которые помогут вам проверить фрагментацию памяти. Что произойдет, если вы выполните выделение 1 ГБ в начале приложения? Boofhead
Я проверю инструменты SysInternals, какие-нибудь советы для них? Я не выделяю 1 ГиБ за один раз. Есть несколько распределений около 300 МБ каждый. Я получаю близко к 1 ГиБ без проблем. 0xbaadf00d
Я могу подумать о двух вещах: меньшем распределении ресурсов и, пожалуйста, о том, что 32-битные операционные системы вне сферы встроенных систем скоро умрут И из-за корпоративной политики я застрял на 32-битной Windows 7 с 2,8 из 4 ГБ используемой памяти, поэтому я желаю ее своевременного прекращения. r_ahlskog

Ваш Ответ

5   ответов
0

я использую функцию Windows VirtualAlloc, чтобы избежать выделения по умолчанию.

Другим способом продвижения вперед может быть использованиеnedmalloc в вашем проекте.

4

Это очень вероятно, чтобы получить больше памяти в небольших кусках

Вы должны перепроектировать свои структуры памяти.

На самом деле нет необходимости, я просто дам меньший буфер, чем требовалось, мой код, похоже, не заботился :) Я сделал цикл, который пытается выделить, если он терпит неудачу, он пытается выделить меньший кусок .. это продолжается до тех пор, пока не заработает. 0xbaadf00d
2

получить около 2 ГБ (3, если вы используете ключ / 3GB boot.ini и флаг ссылки LARGEADDRESSAWARE), но не как большой непрерывный блок.

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

Вы можете быстро проверить это, написав небольшой цикл выделения, который выделяет блоки разных размеров.

11

в целом.

В Windows половина этого является запрещенной, поэтому ваш процесс имеет 2 ГБ.

Это 2 ГБ непрерывной памяти. Но это становится фрагментированным. Ваш исполняемый файл загружается по одному адресу, каждая DLL загружается по другому адресу, затем есть стек, выделения кучи и так далее. Таким образом, хотя ваш процесс, вероятно, имеет достаточно свободного адресного пространства, нет непрерывных блоков, достаточно больших для выполнения ваших запросов памяти. Таким образом, выделение меньших средств, вероятно, решит эту проблему.

Если ваше приложение скомпилировано с флагом LARGEADDRESSAWARE, ему будет разрешено использовать столько оставшихся 2 ГБ, сколько может выделить Windows. (И ценность этого зависит от вашей платформы и среды.

для 32-разрядного кода, работающего в 64-разрядной ОС, вы получите полное 4-ГБ адресное пространстводля 32-битного кода, работающего на 32-битной ОС без загрузочного переключателя / 3GB, флаг вообще ничего не значитдля 32-битного кода, работающего на 32-битной ОС с переключателем загрузки / 3GB, вы получите 3 ГБ адресного пространства.

На самом деле, установка флага - это всегда хорошая идея, если ваше приложение может с этим справиться (это в основном флаг возможностей. Он говорит Windows, чтомы может обрабатывать больше памяти, поэтому, если Windows тоже может, она должна просто пойти дальше и предоставить нам как можно большее адресное пространство), но вы, вероятно, не можете полагаться на то, что это даст эффект. Если вы не работаете на 64-битной ОС, вряд ли вы много купите. (Требуется ключ загрузки / 3GB, и, как известно, он вызывает проблемы с драйверами, особенно с драйверами видео)

Я просто не верил, что мое программное обеспечение будет так сильно фрагментировать память, но, похоже, это так и есть :) Я получил около 1,6 ГБ, создав обработчик исключений, который пытается выделять все меньшие и меньшие фрагменты, пока это не удастся. Я попытался использовать флаг LARGEADDRESSAWARE, но я не использовал переключатель 3GB. Я упоминал, что это повлияет на производительность программы, правда ли это / большой? 0xbaadf00d
Я пытался спроектировать таким образом, чтобы он этого не делал: / Видимо, у меня ничего не получилось. 0xbaadf00d
В XP вы также должны использовать ключ / 3GB boot.ini. holtavolt
@justanothercoder: без параметра / 3GB в XP LARGEADDRESSAWARE не добьется большого успеха - см. эту страницу для получения информации о его включении:msdn.microsoft.com/en-us/windows/hardware/gg487508 Я никогда не испытывал каких-либо заметных проблем с производительностью при использовании этой конфигурации, хотя некоторые драйверы видео имели проблемы при включении этого режима - я не знаю, так ли это до сих пор. holtavolt
@justanothercoder: ну, очень легко вызвать фрагментацию. Выделите один байт в нужном месте, и ваше адресное пространство объемом 2 ГБ было уменьшено до двух адресных пространств объемом 1 ГБ. Еще два байта в нужных местах, и у вас есть четыре 512 МБ. Конечно, обычно выделения размещаются для минимизации фрагментации, но я хочу сказать, что очень просто фрагментировать пространство памяти. jalf
1

это функция от MSDN. 1GB звонит в звонок отсюда:

Этот параметр должен быть больше или равен 13 страницам (например, 53 248 в системах с размером страницы 4 КБ) и меньше общесистемного максимума (количество доступных страниц минус 512 страниц). Размер по умолчанию составляет 345 страниц (например, это 1 413 120 байт в системах с размером страницы 4 КБ).

Здесь они упомянули, что максимальное количество страниц по умолчанию, разрешенное для процесса, составляет 345 страниц, что чуть больше 1 ГБ.

Похожие вопросы