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

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

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

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


person Roman Starkov    schedule 13.04.2011    source источник


Ответы (1)


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

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

Вам нужно GetProcessMemoryInfo

EDIT:
Поскольку теперь ясно, что вы не использовали неправильный 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.

person Damon    schedule 13.04.2011
comment
О, чёрт, я подключил не ту функцию... На самом деле я использую WorkingSet64, свойство .NET. Я хотел сделать вопрос нейтральным к языку, но, очевидно, потерпел неудачу :) Я не верю, что путаница с минимальным/максимальным значением является настоящей проблемой. - person Roman Starkov; 14.04.2011
comment
Хм... VMMap, единственный известный мне инструмент, который правильно считает все RAM, рассказывает другую историю о VirtualBox. А именно, что вся используемая память фактически заблокирована. Возможно, в вашем случае он не может заблокироваться из-за того, что слишком мало оперативной памяти или работает на 32-битном хосте? Я хотел бы увидеть, что VMMap говорит для ваших двух VirtualBox. - person Roman Starkov; 16.04.2011