Новые Windows 8.1 API для управления виртуальной памятью: `DiscardVirtualMemory()` vs `VirtualAlloc()` и `MEM_RESET` и`MEM_RESET_UNDO`

Windows 8.1/Server 2012RC2 только что представила новые API для управления виртуальной памятью: OfferVirtualMemory(), ReclaimVirtualMemory(), DiscardVirtualMemory(), что их использование довольно просто, просто посмотрев на их имена.

Я не могу понять, как эти API работают против VirtualAlloc() плюс флаги MEM_RESET а также MEM_RESET_UNDOи каковы тонкие различия.

Для OfferVirtualMemory()MSDN говорит, что очень похоже на VirtualAlloc()+MEM_RESETза исключением того, что он удаляет страницы из рабочего набора и ограничивает дальнейший доступ к страницам.

Итак, в основном это ограничивает доступ к страницам, и если я хочу получить доступ к этим страницам снова, я должен позвонить ReclaimVirtualMemory()и это нормально, но не должно MEM_RESET также удаляет страницы из рабочего набора? не должны MEM_RESET действовать как POSIX MADV_DONTNEED флаг madvise(2) который в основном удаляет страницы из таблиц страниц процесса, и если в будущем я снова получу доступ к этим страницам, при доступе произойдет программная ошибка, и эти страницы будут снова перераспределены, инициализированы нулем.

Если это так, конечно, страницы удаляются из рабочего набора процесса, потому что они в основном освобождаются, даже если процесс сохраняет выделенные виртуальные адреса и видит их "зафиксированными".

Теперь посмотрим DiscardVirtualMemory(): здесь MSDN ничего не говорит о MEM_RESET флаг, но если я читаю описание этого API, кажется, действительно то же самое, что и VirtualAlloc()+MEM_RESET,

Итак, кто-нибудь знает, есть ли какие-то различия между этими API, и каковы правильные варианты использования этих тонких различий? Если они представили совершенно новый API, как DiscardVirtualMemory(), должна быть какая-то разница со старым методом.

Если я хочу портировать приложение из POSIX, которое использует madvise(2) с MADV_DONTNEED а также MADV_WILLNEEDКаков наилучший способ имитировать это поведение POSIX? До сих пор я использовал VirtualAlloc()+MEM_RESET за MADV_DONTNEED а также VirtualAlloc()+MEM_RESET_UNDO за MADV_WILLNEED, Это нормально, или я могу лучше работать с этими новыми API?

1 ответ

Решение

DiscardVirtualMemory на MSDN

Когда приложение снова обращается к области памяти, резервное ОЗУ восстанавливается, и содержимое памяти не определено.

Если я читаю между строк, это говорит:

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

Это не то, что произойдет, если вы сбросите диапазон виртуальных адресов с помощью более старого API. В этом случае есть гарантия предоставления нулевых инициализированных страниц при последующем доступе к этим страницам.

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

Другие вопросы по тегам