Почему заблокированные страницы не учитываются в размере рабочего набора?

#windows #winapi #paging #virtual-memory

#Windows #winapi #подкачка #виртуальная память

Вопрос:

Цель VirtualLock вызова WinAPI — заблокировать страницы в рабочем наборе процесса. Однако WorkingSet64 API необъяснимым образом не учитывает эти страницы.

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

Что с этим не так? Может ли кто-нибудь, хорошо знакомый с виртуальной памятью в WinNT, пролить свет на это несоответствие, из-за которого гигабайты используемой оперативной памяти остаются практически незамеченными? (подумайте о SQL Server или VirtualBox)

Ответ №1:

Ах, это легко объясняется: вы используете неправильный API. GetProcessWorkingSetSize запрашивает минимальный и максимальный размеры рабочего набора. Это квоты, а не фактические значения.

Минимальный размер рабочего набора — это тот, который Windows гарантированно сохранит заблокированным в оперативной памяти до тех пор, пока не наступит конец света. Максимальный размер рабочего набора — это объем памяти, который Windows предоставит вашему процессу до перемещения страниц в пул (они не обязательно исчезают, но доступ к ним вызывает сбой и повторное сопоставление).

Вы хотите получить Processmemoryinfo

РЕДАКТИРОВАТЬ:
Поскольку теперь ясно, что вы использовали не тот API (только назвали не ту функцию), я провел некоторое тестирование ( VirtualAlloc и файлов с отображением памяти, оба в сочетании с VirtualLock ) в моей системе XP. На первый взгляд, казалось, что вы абсолютно правы. Выделение 512 МБ или сопоставление памяти 512 МБ из файла размером 650 МБ добавило 512 МБ к виртуальному размеру, но не увеличило рабочий набор. Следующее за VirtualLock(512MB) никак не повлияло на рабочий набор!

Затем мне пришло в голову, что VirtualLock в каждом случае потребовалось ровно ноль времени, что не казалось правдоподобным, например, для извлечения половины гигабайта с диска. Итак, я проверил код возврата и угадайте что. Windows не считает блокировку 512 МБ хорошей идеей и откажется это делать.

Повторил эксперимент только с 64 МБ, и вот, рабочий набор сразу увеличился на 64 МБ, как и должно быть. Итак, одним словом: «у меня работает».

Просто чтобы убедиться, вы проверили код возврата?

При повторном взгляде это поведение даже четко определено и хорошо документировано. В документах должно VirtualLock быть указано явно:

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

С блокировкой и без нее, после соответствующей настройки квот WS:

VirtualBox — это другое дело, то, что вы видите в диспетчере задач, — это только рабочий набор программы «Интерфейс» и интерфейса «Менеджер», оба из которых постоянно поддерживают размеры рабочего набора ниже 64M. Хотя я не уверен, какую память он, возможно, выделяет в некоторых драйверах, или если они вообще блокируют память.

В настоящее время я запускаю 2 виртуальные машины с объемом оперативной памяти 1,6 ГБ каждая. Учитывая, что моя 32-разрядная Windows видит только 3,25 ГБ, это оставило бы всего 50 МБ на случай, если память, принадлежащая виртуальным машинам, заблокирована. Кроме того, Process Explorer сообщает мне, что только у Firefox рабочий набор составляет 474 МБ и увеличивается, пока я набираю это (святой … ?!!). Это не делает вероятным, что вся память на виртуальных машинах действительно заблокирована, потому что тогда такие цифры были бы совершенно невозможны.

Как и было запрошено, вот снимок VMMap: введите описание изображения здесь

Цифры, по общему признанию, забавные… всего на виртуальной машине 1,6 Млн, из которых, согласно VMMap, зарезервировано 821 МБАЙТ и зафиксировано 772 мбайт, Process Explorer показывает только 163 МБАЙТ и 54 мбАйТ соответственно. Что-то здесь определенно подозрительно, но я подозреваю, что это, вероятно, какой-то непонятный взлом VirtualBox, а не проблема Windows.

Комментарии:

1. О, черт возьми, я подключил неправильную функцию… На самом деле я использую WorkingSet64 , свойство .NET. Я хотел сделать вопрос нейтральным к языку, но, очевидно, потерпел неудачу 🙂 Я не думаю, что путаница в min / max является реальной проблемой здесь.

2. Хм… VMMap , единственный известный мне инструмент, который правильно подсчитывает всю оперативную память, рассказывает другую историю о VirtualBox. А именно, что вся используемая память фактически заблокирована . Возможно, в вашем случае он не может заблокироваться из-за того, что просто слишком мало оперативной памяти или работает на 32-разрядном хосте? Я бы хотел посмотреть, что говорит VMMap для ваших двух виртуальных ящиков.