Разница вот в чем: с MEM_RESERVE
вы, по сути, говорите операционной системе: «Эй, пожалуйста, мне нужен этот непрерывный блок страниц виртуальной памяти, не могли бы вы дать мне адрес памяти, который соответствует моим потребностям?»
А операционная система вычисляет, где зарезервировать ваш блок. Но он пока ничего не выделяет. (Чтобы увидеть, как это делает операционная система, просто посмотрите такие книги, как «Windows Internals 5th» Марка Руссиновича — подсказка: поищите в Google о деревьях VAD).
Итак, когда вы резервируете блок памяти, операционная система просто выделяет «узел» где-то в дереве или подобную структуру, говоря, что эти адреса зарезервированы, точно так же, как стол в ресторане, и это не может быть используется в других вызовах VirtualAlloc()
.
Вместо этого, когда вы фактически фиксируете страницы с помощью MEM_COMMIT
, операционная система фактически выделяет страницы виртуальной памяти в блоке, который вы зарезервировали ранее. Конечно, вы можете зафиксировать страницы только в тех блоках, которые вы зарезервировали ранее. Не делать этого — все равно, что зарезервировать места в ресторане, а затем сесть за другой столик, не зарезервированный вами.
ПРИМЕЧАНИЕ. Страницы на самом деле не выделяются при их фиксации, так как вы читаете/записываете их (ошибка программной страницы). Это очень полезная оптимизация.
ПРИМЕЧАНИЕ 2: Тот факт, что вы можете ИЛИ MEM_RESERVE|MEM_COMMIT
, просто полезен, поэтому вам не нужно вызывать API `VirtualAlloc()' два раза, но на самом деле это две совершенно разные операции.
ПРИМЕЧАНИЕ 3. Флаг MEM_COMMIT
будет фиксировать страницы на границе размера страницы, а использование MEM_RESERVE
или MEM_RESERVE|MEM_COMMIT
будет резервировать или резервировать + фиксировать страницы на границе, превышающей размер страницы, обычно 64 КБ во всех версиях Windows с сегодняшнего дня. Вы можете получить этот номер, позвонив по номеру GetSystemInfo()
.
person
Marco Pagliaricci
schedule
23.07.2015