отслеживать распределение памяти C ++ - PullRequest
45 голосов
/ 26 мая 2009

Я ищу способ отслеживать распределение памяти в программе на C ++. Я не заинтересован в утечках памяти, которые, похоже, пытаются найти большинство инструментов, а скорее создает профиль использования памяти для приложения. Идеальным выводом будет либо большой список имен функций плюс количество максимально выделенных байтов с течением времени, либо, что еще лучше, графическое представление кучи с течением времени. Горизонтальная ось - это время, вертикальная ось - куча пространства. Каждая функция получает свой цвет и рисует линии в соответствии с выделенными байтами кучи. Бонусные баллы за выявление выделенных типов объектов.

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

Я кратко посмотрел на Purify, BoundsChecker и AQTime, но, похоже, они мне не подходят. Valgrind выглядит подходящим, однако я на Windows. Memtrack выглядит многообещающе, но требует значительных изменений исходного кода.

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

Ответы [ 8 ]

31 голосов
/ 26 мая 2009

Используйте Valgrind и его инструмент Massif. Его пример вывода (часть):

99.48% (20,000B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->49.74% (10,000B) 0x804841A: main (example.c:20)
| 
->39.79% (8,000B) 0x80483C2: g (example.c:5)
| ->19.90% (4,000B) 0x80483E2: f (example.c:11)
| | ->19.90% (4,000B) 0x8048431: main (example.c:23)
| |   
| ->19.90% (4,000B) 0x8048436: main (example.c:25)
|   
->09.95% (2,000B) 0x80483DA: f (example.c:10)
  ->09.95% (2,000B) 0x8048431: main (example.c:23)

Итак, вы получите подробную информацию:

  • ВОЗ выделила память (функции: g (), f () и main () в приведенном выше примере); вы также получаете полную обратную трассировку, ведущую к функции выделения,
  • в какую структуру данных уходит память (без структур данных в приведенном выше примере),
  • КОГДА это произошло,
  • какой процент всей выделенной памяти это (г: 39,7%, ф: 9,95%, основная: 49,7%)

Вот Руководство по массиву

Вы можете отслеживать распределение кучи, а также распределение стека (по умолчанию отключено).

PS. Я только что прочитал, что вы на Windows. Я оставлю ответ, потому что он дает представление о том, что вы можете получить из возможного инструмента.

18 голосов
/ 26 мая 2009

Microsoft имеет хорошо документированные функции отслеживания памяти. Однако по какой-то причине они не очень известны в сообществе разработчиков. Это функции отладки ЭЛТ. Хорошей отправной точкой будет CRT Debug Heap functions .

Проверьте следующие ссылки для более подробной информации

  1. Функции отчетов о состоянии кучи
  2. Отслеживание запросов на выделение кучи . Вероятно, это та функциональность, которую вы ищете.
13 голосов
/ 26 мая 2009

Для обычного трекера памяти C ++ вам потребуется перегрузить следующее:

global operator new
global operator new []
global operator delete
global operator delete []
any class allocators
any in-place allocators

Хитрый бит - получение полезной информации, перегруженные операторы имеют информацию о размере только для распределителей и указатели памяти для удалений. Один из ответов - использовать макросы. Я знаю. Насти. Пример - место в шапке, которая включена из всех исходных файлов:

#undef new

void *operator new (size_t size, char *file, int line, char *function);
// other operators

#define new new (__FILE__, __LINE__, __FUNCTION__)

и создайте исходный файл с:

void *operator new (size_t size, char *file, int line, char *function)
{
  // add tracking code here...
  return malloc (size);
}

Вышеприведенное работает только в том случае, если у вас нет нового оператора, определенного в области видимости класса. Если у вас есть некоторые в области видимости класса, выполните:

#define NEW new (__FILE__, __LINE__, __FUNCTION__)

и замените «новый тип» на «новый тип», но это может потребовать изменения большого количества кода.

Поскольку это макрос, удаление трекера памяти довольно просто, заголовок становится:

#if defined ENABLED_MEMORY_TRACKER
#undef new

void *operator new (size_t size, char *file, int line, char *function);
// other operators

#define NEW new (__FILE__, __LINE__, __FUNCTION__)
#else
#define NEW new
#endif

и файл реализации:

#if defined ENABLED_MEMORY_TRACKER
void *operator new (size_t size, char *file, int line, char *function)
{
  // add tracking code here...
  return malloc (size);
}
endif
7 голосов
/ 01 сентября 2009

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

Я также получил много полезных ответов в SWENG (Список рассылки по разработке программного обеспечения). Поток называется «[Sweng-Gamedev] мониторинг использования памяти C ++?».

1 голос
/ 26 мая 2009

Попробуйте также: Проверка памяти

0 голосов
/ 05 января 2016

«Графическое представление кучи во времени» - то, что вам нужно, реализовано в Intel (R) Single Event API , подробности можно найти в этой статье (это довольно большой, чтобы поставить его здесь). Memory block allocations over time

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

0 голосов
/ 22 октября 2015

В Xcode вы можете использовать инструменты для отслеживания распределения, использования виртуальной машины и некоторых других параметров. В основном популярен среди разработчиков iOS, но стоит попробовать.

0 голосов
/ 26 мая 2009

В Mac OS X вы можете использовать инструмент профилирования кода Shark для этого, IIRC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...