Что такое личные байты, виртуальные байты, рабочий набор?

Я пытаюсь использовать служебную программу perfmon для отладки утечек памяти в процессе.

Вот как perfmon объясняет термины:

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

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

Частные байты - это текущий размер в байтах памяти, выделенный этим процессом, который не может использоваться совместно с другими процессами.

Вот те вопросы, которые у меня есть:

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

Какова общая память, потребляемая процессом? Это виртуальные байты или это сумма виртуальных байтов и рабочего набора?

Есть ли связь между частными байтами, рабочим набором и виртуальными байтами?

Существуют ли какие-либо другие инструменты, которые дают лучшее представление об использовании памяти?

Ответ 1

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

Частные байты относятся к объему памяти, который запросил исполняемый файл процесса, - не обязательно, сколько он фактически использует. Они "private", потому что они (обычно) исключают файлы с отображением памяти (т.е. Общие библиотеки DLL). Но - вот улов - они не обязательно исключают память, выделенную этими файлами. Невозможно определить, связано ли изменение в частных байтах с самим исполняемым файлом или из-за связанной библиотеки. Частные байты также являются не исключительно физической памятью; они могут быть выгружены на диск или в список резервных страниц (т.е. больше не используются, но еще не выгружены).

Рабочий набор относится к общей физической памяти (ОЗУ), используемой процессом. Однако, в отличие от частных байтов, это также включает в себя файлы с отображением памяти и различные другие ресурсы, поэтому это еще менее точное измерение, чем частные байты. Это то же самое значение, которое сообщается в диспетчере задач "Mem Usage" и в последние годы стало источником бесконечной путаницы. Память в рабочем наборе "физическая" в том смысле, что ее можно решить без ошибки страницы; однако список резервных страниц также по-прежнему физически находится в памяти, но не сообщается в рабочем наборе, и именно поэтому вы можете внезапно отказаться от использования "Mem Usage" при минимизации приложения.

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

Итак, отношения:

  • Частные байты - это то, что ваше приложение действительно выделило, но включите использование файла подкачки;
  • Рабочий набор - это незашифрованные частные байты плюс файлы с отображением памяти;
  • Виртуальные байты - это рабочий набор плюс индивидуальные байты и резервный список.

Здесь есть еще одна проблема; так как разделяемые библиотеки могут выделять память внутри вашего прикладного модуля, что приводит к потенциальным ложным срабатываниям, указанным в вашем приложении Private Bytes, ваше приложение также может распределить память внутри общих модулей, что приведет к ложным негативам. Это означает, что на самом деле приложение может иметь утечку памяти, которая вообще не проявляется в частных байтах. Вряд ли, но возможно.

Частные байты являются разумным приближением объема памяти, который использует ваш исполняемый файл, и могут быть использованы для сужения списка потенциальных кандидатов на утечку памяти; если вы видите, что число растет и растет постоянно и бесконечно, вы бы хотели проверить этот процесс на утечку. Это не может, однако, доказать, что есть или нет утечки.

Один из самых эффективных инструментов для обнаружения/исправления утечек памяти в Windows на самом деле Visual Studio (ссылка идет на страницу об использовании VS для памяти утечки, а не страницы продукта). Rational Purify - еще одна возможность. Microsoft также имеет более общий список лучших практик по этому вопросу. В этом предыдущем вопросе есть дополнительные инструменты.

Надеюсь, это прояснит некоторые вещи! Отслеживание утечек памяти - одна из самых сложных задач в отладке. Удачи.

Ответ 2

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

Предыдущий ответ на этот вопрос дал большое объяснение того, что представляют собой различные типы.

Вы спрашиваете о рекомендации инструмента: Я рекомендую Memory Validator. Возможность мониторинга приложений, которые делают миллиарды распределений памяти.

http://www.softwareverify.com/cpp/memory/index.html

Отказ от ответственности: я создал Memory Validator.

Ответ 3

Здесь интересная дискуссия: http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/307d658a-f677-40f2-bdef-e6352b0bfe9e/ Мое понимание этой темы заключается в том, что освобождение небольших распределений не отражается в частных байтах или рабочем наборе.

Короче говоря:

если я вызываю

p=malloc(1000);
free(p);

тогда частные байты отражают только распределение, а не освобождение.

если я вызываю

p=malloc(>512k);
free(p);

тогда частные байты правильно отражают распределение и освобождение.

Ответ 4

Определение счетчиков perfmon было нарушено с самого начала и по какой-то причине кажется слишком трудным для исправления.

Хороший обзор управления памятью Windows доступен в видеоролике "" Тайны управления памятью" на MSDN: он охватывает больше тем, чем необходимо для отслеживания утечек памяти (например, управления рабочими наборами), но дает достаточно подробностей в соответствующих темах.


Чтобы дать вам намек на проблему с описаниями счетчиков perfmon, вот внутренняя история о частных байтах из " счетчик производительности личных байтов - остерегайтесь!" в MSDN:

В: Когда частный байт не является частным байтом?

A: Когда он не резидент.

Счетчик личных байтов сообщает об фиксации процесса. То есть объем пространства, выделенного в файле подкачки, для хранения содержимого частной памяти в случае его замены. Примечание. Я избегаю слова "зарезервировано" из-за возможной путаницы с виртуальной памятью в зарезервированном состоянии, которое не выполняется.


От " Планирование производительности" на MSDN:

3.3 Частные байты

3.3.1 Описание

Частная память определяется как память, выделенная для процесса, который не может использоваться другими процессами. Эта память более дорогая, чем разделяемая память, когда несколько таких процессов выполняются на машине. Частная память в (традиционных) неуправляемых DLL обычно представляет собой статику С++ и составляет порядка 5% от общего рабочего набора dll.