За много лет использования Windows я привык к Диспетчеру задач. Оттуда я убил сотни приложений за плохое поведение. Там же смотрел, кто из них пожирает ресурсы. Пока я не начал работать с машинами, у которых сотни гигабайт памяти, а у приложений соответствующие запросы. В этой статье обсудим, почему Диспетчер задач плохо отслеживает память и что использовать взамен. Во-первых, о механизме выделения памяти в Windows.

tl;dr: Диспетчер задач скрывает информацию о подкачке (paged memory) и виртуальном пространстве процесса. Лучше используйте Process Explorer из комплекта Sysinternals.

Выделение памяти в Windows


При запуске нового процесса ОС присваивает этому процессу непрерывное адресное пространство. В 32-разрядных системах это пространство может составить 4 ГБ, обычно 2 ГБ для ядра, а остальное для процесса. В этой статье проигнорируем использование памяти ядром. В 64-разрядных системах зарезервированная процессом память может вырасти до колоссальных 64 ТБ. Что этот процесс будет делать с несколькими терабайтами памяти, когда у нас на самом деле жалкие 8 ГБ? Сначала нужно понять, что такое зарезервированная и переданная память.

Зарезервированная и переданная память


Не все части этого огромного адресного пространства равны. Некоторые части адресного пространства процесса фактически поддерживаются либо физической оперативной памятью, либо диском (см. ниже). Зарезервированная память считается переданной (Committed), если ОС предлагает вам эту память при попытке её использовать. Остальная часть адресного пространства, а это подавляющее большинство, остаётся доступным для резервирования. То есть не всегда ОС может предложить вам этот блок памяти для использования: она может сделать копию на диске (файл подкачки), например, а может и не сделать. В C++ резервирование памяти осуществляется вызовом VirtualAlloc. Так что переданная память является аппаратно ограниченным ресурсом в ОС. Давайте посмотрим.

Файл подкачки ОС


Файл подкачки — замечательная идея. В принципе, ОС понимает, что некоторые части памяти особо не используются вашим приложением. Зачем тратить на него реальную физическую память? Вместо этого процесс в ядре записывает этот неиспользуемый фрагмент на диск. Пока к нему не обратятся снова, только тогда он вернётся в память.

Для более подробного объяснения, как работает память в Windows, рекомендую лекцию «Тайны управления памятью» Марка Руссиновича.

Отслеживание памяти


Здесь много за чем нужно следить и анализировать. К кому обратиться? Конечно, к Диспетчеру задач!

Память в RAM обычно называют рабочим набором (Working Set), в то время как всю выделенную память обычно именуют Private Bytes. Библиотеки DLL вносят путаницу в определения, поэтому пока их проигнорируем. Иначе говоря:

Private Bytes [выделенная память] = рабочий набор + файл подкачки

По умолчанию Диспетчер задач показывает для любого процесса именно рабочий набор:



И это число, на которое я всё время смотрел. Откуда я знал, что в Диспетчере задач информация о переданной памяти находится в колонке Commit Size. Я так и не смог там найти информацию о виртуальной памяти.


Диспетчер задач позволяет добавить информацию о переданной памяти, если щёлкнуть правой кнопкой мыши по столбцам и выбрать соответствующий пункт

Эффективные метрики памяти


К счастью, есть много других ресурсов для отслеживания ресурсов. На каждой машине под Windows установлен PerfMon (Системный монитор), который выдаёт очень подробную информацию о каждом процессе и системе в целом:



Интересно, что Системный монитор умеет фактически исследовать и сравнивать метрики на двух или более компьютерах в сети. Это очень мощный инструмент, но Диспетчер задач, очевидно, удобнее для пользователей. В качестве промежуточного решения рекомендую Process Explorer:



Бум! Visual Studio, чего это ты до сих пор в 32-битном режиме (обратите внимание на его Virtual Size)? Пиковое использование памяти на моём компьютере на уровне 89% от максимума, ещё терпимо. Это пригодится позже.

Дополнение: многие указали на другие удобные инструменты, в том числе VMMap и RAMMap.

Отладка по информации о памяти


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

Самое главное, это найти нетронутые части выделенной памяти. Данные о подкачке тоже важны: эта память передана, но используется редко или вообще не используется.

Даже если память будет иногда использоваться, важно понимать, что это дорогой ресурс, так что идти по такому пути ни в коем случае нельзя. Здесь появятся и утечки памяти.

По этим причинам я ранее слышал предложение полностью удалить файл подкачки и приравнять выделенную память рабочему набору. Однако это обоюдоострая идея. Тогда ОС не в состоянии сбросить память в случае неправильной работы приложений, которые иногда впустую резервируют память.

Комментарии (19)


  1. nerudo
    10.01.2019 21:19
    +3

    tl;dr: Автор не освоил даже диспетчер задач и решил, что process explorer его спасет.


    1. qw1
      10.01.2019 22:02
      +2

      При этом, автор считает, что при удалении файла подкачки Private Working Set будет равен Commit Size, что неверно хотя бы потому, что отмапленные в память EXE и DLL файлы сразу будут занимать весь Commit Size, но подкачиваться в Working Set при необходимости, удаление pagefile на это не влияет. Подкачка исполнимых файлов запрещается другим способом.


  1. Kobalt_x
    10.01.2019 21:31
    +3

    Я дико извиняюсь, и да, я вижу, что это перевод, но эта тема уже освещалась довольно подробно хабраюзером amirul
    habr.com/post/107605


    1. Focushift
      11.01.2019 14:26

      К примеру той статьи я не видел, мне лично полезной оказалась эта, прошло 8 лет.
      Что тогда с автором предложите делать?


      1. Kobalt_x
        11.01.2019 17:51

        Просто в той статье уже всё довольно подробно разобрано до базовых принципов понятным русским языком. За 8 лет в Memory managmentе windows NT ничего из того что затронуто в этом переводе.
        А так можно дайти что каждые 5 лет кто-то заново будет открывать для себя windows internals Руссиновича и постить «открытия» сюда.


  1. alexanster
    10.01.2019 22:58
    +1

    Private Bytes [выделенная память] = рабочий набор + файл подкачки
    Запустил Process Explorer. Практически у всех процессов Private Bytes меньше рабочего набора. Видимо файл подкачки отрицательный.


    1. CoolCmd
      10.01.2019 23:21

      не знаю, почему автор поместил файл подкачки в эту формулу. privates bytes вычитает из working set память, которая совместно используется несколькими приложениями. например, любое win32 приложение использует ntdll.dll. его в private bytes не будет.


  1. Alexufo
    11.01.2019 03:22
    +1

    Process Explorer не может выделить кликом мышки с shift несколько процессов.
    И еще много не очень удобных вещей.
    Потому полностью перешел на

    processhacker.sourceforge.io


    1. lyadnov
      11.01.2019 13:20
      -1

      он давненько не обновлялся


      1. Xalium
        11.01.2019 14:21

        там есть ссылка на гитхаб, на котором есть ссылка на офф. ночные сборки (не знаю есть ли в них плагины).
        + на forum.ru-board.com юзер с ником Victor_VG тоже выкладывает свои сборки (туда и плагины входят).


  1. InvestJournal
    11.01.2019 07:11

    У Task Manager совсем иная задача — он показывает зрителю очень важный экран очень важного компьютера. Task Manager, раскрытый на весь экран, убедительно формирует антураж напряжённой атмосферы комнаты допроса или бункера командного пункта управления ответным ядерным ударом.


    1. PKav
      11.01.2019 11:57

      То есть для имитации бурной деятельности перед начальством? Да не особо оно подходит. Раньше для этого использовали tail -f /var/log/squid/access.log или что-то подобное.


      1. InvestJournal
        11.01.2019 12:59

        Скорее, перед режиссёром ) Первый раз увидел Task Manager во всей красе в «документальном» фильме REN-TV о ядерном щите, второй — в сериале с Охлобыстиным (не вспомню сейчас название, производство Star Media), в обоих случаях экрану с TM уделена масса операторского времени, хотя увязать линии расхода RAM и нагрузки CPU с сюжетом невозможно.


        1. Am0ralist
          11.01.2019 14:37

          Не удержался и повторю один свой коммент:
          image


  1. Serge78rus
    11.01.2019 10:01

    В C++ резервирование памяти осуществляется вызовом VirtualAlloc.
    Непонятно, причем здесь язык C++. Разве в C это работает как то иначе?


  1. Revertis
    11.01.2019 13:21

    А как увидеть память, выделенную драйвером RAM-диска? Что-то даже process explorer не показывает, либо я не нашёл.


  1. Focushift
    11.01.2019 14:31

    Подскажите?
    В таскменеджере можно увидеть сколько РЕАЛЬНО доступно оперативной памяти?

    У меня ноутбук с процессором интел и 8ГБ оперативы, но если использование памяти приближается к отметке 6,5-7ГБ, начинают крошиться приложения и вкладки хрома.
    Я так понимаю видеокарта втихаря зажала 1гиг оперативы, а система молчит?


    1. ggreminder
      12.01.2019 23:31

      Видеокарта ничего не жрала втихаря, можно посмотреть максимально доступное количество памяти через Control Panel\System and Security\System или во вкладке Performance -> Memory в Task Manager. И там, и там написано большее число — installed memory и меньшее — usable memory.
      Вообще, это странно что прям приложения крешатся (вкладки хрома бывало, да). Давно такого поведения не наблюдал, может замедлиться при выделении дополнительной виртуальной памяти. Посмотрите, что у вас стоит в настройках файла подкачки (Control Panel\System and Security\System -> Advanced System Settings -> Performance -> Settings -> Advanced -> Virtual Memory).


    1. Andrey_Vladimirovich
      13.01.2019 11:27

      Focushift, так, а файл подкачки вы используете? Почему что-то крошится? Если тормозит, то понятно.