Alexander Kindel Ответов: 3

Как windows отслеживает зарезервированную виртуальную память?


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

Эта схема основана на том, чтобы знать, что никакие случайные распределения не будут сделаны между текущим концом одной арены и началом следующей. Однако я буду использовать winAPI для своего графического интерфейса, который, по-видимому, будет выделять в моем адресном пространстве, и, насколько я вижу, я не могу диктовать его распределителям, где им это разрешено. Похоже, что вместо этого мне придется везде указывать его не разрешено выделять, вызывая VirtualAlloc с MEM_RESERVE, и поскольку чем шире разнесены арены, тем лучше, я бы предпочел, чтобы это повлекло за собой столько моего адресного пространства, сколько мне сойдет с рук.

So...would making a reservation of such a large span cause any kind of pathological behavior? People have suggested that it would gunk up Windows' system for tracking virtual memory, but never with a concrete enough explanation of how to convince me to give up on the idea. I understand that for committed memory, the OS must enumerate each page since it needs to specify how the page is mapped to physical memory. In other words, the amount of work scales with the amount of memory committed. If memory that is merely reserved is treated the same way, then my large reservation would indeed stress the system. However, since reserving lacks the complication of mapping to physical memory, I can imagine that instead of enumerating each page, it only keeps track of the start and end of each reservation. In that case, the amount of work would scale with the количество бронирований и Моя гигантская резервация была бы не хуже , чем резервация одной страницы.

Что я уже пробовал:

Чтение о модели виртуальной памяти Windows.

3 Ответов

Рейтинг:
2

Richard MacCutchan

Взгляните на это VMMap - Windows Sysinternals | Microsoft Docs[^], что может оказаться полезным.


Рейтинг:
2

Alexander Kindel

I tried writing a program that does nothing but reserve some memory then block - I initially tried reserving half the difference between lpMaximumApplicationAddress and lpMinimumApplicationAddress. Then I ran the program and found it in Task Manager. The memory column said 128.3MB. I tried halving the size of the reservation and running it again; Task Manager then reported 64.3MB. Halving the size of the reservation a few more times halved the value Task Manager reported each time. So it would seem that Windows does do something like enumerating every page, even just for reservations, and the people who warned me not to make large reservations were right to be wary.

Кроме того, я сделал озадачивающее наблюдение: я попытался увеличить резервацию до ее первоначального, очень большого размера, но сразу же после этого добавил к ней виртуальный бесплатный вызов. Значение, сообщенное Диспетчером задач, оставалось стабильным на уровне 128,3 МБ, а не падало обратно после освобождения. Так что, по-видимому, если память будет связана с отслеживанием резервации в любой момент, нет никакого способа вернуть ее обратно.


Рейтинг:
1

Gerry Schmitz

Если ваш рабочий набор больше реальной памяти, то у вас есть подкачка (в / из виртуального хранилища [диска]).

Если ваш доступ к памяти "повсюду", то вы получаете "больше" подкачки.

Если ваша подкачка становится чрезмерной, то вы получаете "взбучку", что приводит к снижению производительности.


Alexander Kindel

Does memory that is reserved but not committed count as being part of the working set? According to https://docs.microsoft.com/en-us/windows/win32/memory/working-set, "the working set of a process is the set of pages in the virtual address space of the process that are currently resident in physical memory" which, according to https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc, reserved memory is not: MEM_RESERVE "reserves a range of the process's virtual address space without allocating any actual physical storage in memory or in the paging file on disk." I don't expect the amount of memory I actually commit to be anything out of the ordinary.