2013-07-03 3 views
1

Я пытаюсь выделить большой блок (5 ГБ) памяти под Windows 7 Professional. У меня 64-разрядная машина и 16 ГБ оперативной памяти, и я использую MS Visual Studio 10. Для тех из вас, кто может спросить, почему - это потому, что мне нужно провести двумерное растровое представление карты ссылочных номеров на многоугольные данные , карты могут составлять до 40 000 х 40 000 единиц. Это должно переместиться в ОЗУ, а фрагментация его на более мелкие блоки будет слишком дорогостоящей во время работы.Как с большими блоками памяти Windows 7

Так что, если я это сделать:

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int t = INT_MAX; 
    int * test = new int[t/6]; 
    delete test; 
    return 0; 
} 

Вызов новый сбой, но int * test = new int[t/7]; успешно.

Исследование немного больше. Я обнаружил, что выделение памяти использует только память, которая указана как «свободная» на мониторе ресурсов. Поэтому, когда это меньше, чем требуемое распределение, распределение не выполняется. Монитор ресурсов сообщает мне, что (когда я смотрел) у меня было ~ 5 ГБ в использовании, ~ 10 ГБ в режиме ожидания и чуть более 1 ГБ бесплатно.

Насколько я понимаю, этого не должно произойти. Конечно, если память запрошена, ее следует взять из резервной памяти? Если это не так, то есть ли способ уменьшить объем резервной памяти, используемой окнами изнутри C++?

Последнее может быть сделано за пределами C++ с использованием RAMMap, как я выяснил из этого сообщения: Clear the windows 7 standby memory programmatically, но, к сожалению, не было никакого полезного ответа на вопрос о программной очистке. Возможно, мне повезло в C++.

Конечно, более вероятный сценарий, что я просто пропущу что-то очевидное.

Благодаря

+0

Попробуйте построить как x64, если вы можете, вам гораздо проще найти большие смежные блоки с 64-разрядным адресным пространством (на самом деле его меньше 64 из-за ограничений, но все же намного больше 32) –

+0

Скомпилировано ли это как 32- или 64-битный код? Потому что я могу выделить 16 ГБ на моем компьютере Linux, в 64-битном режиме (он имеет 16 ГБ ОЗУ, поэтому он будет меняться, когда он это сделает). Ваш тест ниже 2 ГБ, что для меня означает, что вы используете 32-разрядный код. –

+0

Ахх, конечно, пропавших без вести было что-то очевидное. Вы правы, его скомпилировали как 32-битный. Компиляция как 64-битная, и проблема уходит.Или, по крайней мере, догадываюсь до тех пор, пока не удастся преодолеть нескончаемый предел памяти, который я еще не сделал. Благодарим вас за то, что спасли мне часы, пытаясь решить проблему неправильно. – user2545038

ответ

2

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

1

Возможно, фрагментация памяти может быть одной из проблем: вы могли иметь этот объем свободной памяти, но он не является непрерывным.

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

С точки зрения производительности: пока вы работаете только с одним куском, вы потеряете скорость, поскольку данные остаются в кэше CPU. Если вы часто переключаетесь между двумя кусками (например, вы меняете предметы между ними), вы получите пропуски кеша.

В любом случае любые обходные пути, такие как очистка памяти, похожи на покер: вы можете получить кусок тогда или нет. Это зависит от слишком многих факторов, которые вы не можете контролировать.

+0

Спасибо, похоже, я сделал глупую ошибку и не думал переходить на 64-битную компиляцию. Но ваш совет очень важен. Я не попал в эту проблему, но это, безусловно, только вопрос времени, прежде чем я это сделаю. Я рассмотрю ссылки-списки как возможное решение - спасибо. – user2545038

Смежные вопросы