Какую часть виртуальной памяти процесса отображает диспетчер задач Windows - PullRequest
0 голосов
/ 18 мая 2018

Мой вопрос немного наивный.Я хочу, чтобы обзор был как можно более простым, и я не смог найти ни одного ресурса, который бы дал мне понять.Я разработчик, и я хочу понять, что именно отображается в столбце «память» по умолчанию в диспетчере задач Windows:

enter image description here

Комунемного упростим ситуацию, давайте забудем о памяти, которую процесс разделяет с другими процессами, и представим, что общая память ничтожна.Также я сосредоточен на общей картине и в основном заботюсь о вещах на уровне ГБ.

Насколько я знаю, память, зарезервированная процессом, называемым «виртуальной памятью», частично хранится в основной памяти (RAM), частично на диске.Система решает, что и куда.Система в основном хранит в ОЗУ те части виртуальной памяти, к которым процесс обращается достаточно часто.Процесс может зарезервировать больше виртуальной памяти, чем ОЗУ, доступной на компьютере.

С точки зрения разработчика, виртуальная память может быть выделена программой только частично через ее собственный менеджер памяти (с malloc() или new X() например).Я полагаю, что система не знает, какая часть виртуальной памяти выделена, поскольку она обрабатывается процессом «приватно» и зависит от языка, времени выполнения, компилятора ... Q: Это правильно?

Моя гипотеза состоит в том, что память, отображаемая диспетчером задач, по сути является частью виртуальной памяти, сохраняемой в ОЗУ системой. В: Это правильно?И есть ли простой способ узнать общую виртуальную память, зарезервированную процессом?

1 Ответ

0 голосов
/ 18 мая 2018

Память на окнах ... чрезвычайно сложна, и вопрос «сколько памяти использует мой процесс» - фактически бессмысленный вопрос.Чтобы ответить на ваши вопросы, давайте сначала разберемся с небольшим фоном.

Память на окнах выделяется через ptr = VirtualAlloc(..., MEM_RESERVE, ...) и фиксируется позже с VirtualAlloc(ptr+n, MEM_COMMIT, ...).

Любая зарезервированная память просто использует адресное пространство и т. Д.не интересноWindows позволит вам MEM_RESERVE терабайт памяти просто отлично.Выделение памяти действительно расходует ресурсы, но не так, как вы думаете.Когда вы вызываете коммит, Windows делает несколько сумм и в основном работает (общий физический RAM + общий своп - текущий коммит) и позволяет вам выделять память, если есть достаточно свободного места.НО менеджер памяти Windows фактически не дает вам физической памяти, пока вы его не используете.

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

Есть еще одно большое предостережение - общая память.Когда вы загружаете код DLL, постоянная память [и даже, возможно, раздел чтения / записи, но это COW'd], может использоваться совместно с другими программами.Это означает, что вашему приложению требуется эта память, но вы не можете сосчитать эту память только с вашим приложением - в конце концов, она может быть разделена и поэтому не занимает столько физической памяти, сколько может показаться наивный подсчет.

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

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

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

Теперь, чтобы ответить на ваши вопросы

Во-первых, ОС точно знает, сколько памяти зарезервировано вашим приложением и сколько оно выделило.Чего он не знает, так это того, что реализация кучи, которую вы (или, более вероятно, CRT) используете, сохранила некоторую освобожденную память, о которой она не вернула обратно в операционную систему.Кучи часто делают это как оптимизацию - запрос памяти у ОС и ее высвобождение обратно в ОС является довольно дорогой операцией (и ее можно выполнять только большими кусками, называемыми страницами), и поэтому большинство из них хранят их немного.

Второй вопрос: не используйте это значение, перейдите к деталям и используйте значения там, поскольку только вы знаете, что на самом деле хотите спросить.

РЕДАКТИРОВАТЬ:

Для вашего комментария, да, но это зависит от размера распределения.Если вы выделяете большой блок памяти (скажем,> = 1 МБ), то куча в CRT, как правило, напрямую откладывает выделение операционной системе, поэтому освобождение отдельных блоков фактически освобождает их.Для небольших выделений куча в CRT запрашивает страницы памяти у операционной системы, а затем подразделяет их для распределения в выделениях.И поэтому, если вы затем освободите все остальные, у вас останутся дыры - и куча не сможет вернуть эти дыры ОС, поскольку ОС обычно работает только на целых страницах.Таким образом, все, что вы увидите в диспетчере задач, покажет, что вся память все еще используется.Помните, что эта память не теряется и не просачивается, она просто эффективно объединяется и будет использоваться снова, если выделение ресурсов потребует такого размера.Если вам не безразлична эта память, вы можете использовать семейство crt статистика кучи функций , чтобы следить за ними, в частности _CrtMemDumpStatistics

...