Меню:


Google Performance Tools (GPT) — набор утилит, которые позволяют проводить анализ производительности программ, а также анализировать выделение памяти программами и производить поиск утечек памяти.

Установка

GPT может работать практически на всех Unix-совместимых операционных системах — Linux, FreeBSD, Solaris, Mac OS X (Darwin), включая поддержку разных процессоров1 — x86, x86_64 и PowerPC. Кроме того, tcmalloc можно скомпилировать также и для MS Windows, что позволит искать утечки памяти в программах, разработанных для этой ОС.

Установка на Unix-совместимые системы достаточна проста — пакет использует стандартную инфраструктуру autotools, так что вам для установки необходимо лишь скачать исходные тексты с сайта проекта и выполнить последовательность команд:

./configure
make
make install

которые выполнят настройку, сборку и установку пакета. Вы можете установить пакет в нужное вам место, задав аргументы команде ./configure.2

Основы работы с GPT

Google Performance Tools состоят из двух библиотек3:

tcmalloc (Thread-Caching Malloc)
tcmalloc — очень быстрая реализация malloc (быстрее чем malloc в glibc 2.3). С помощью данной библиотеки можно анализировать выделение памяти в программе, а также производить поиск утечек памяти. Про внутреннее устройство tcmalloc можно прочитать на сайте проекта.
profiler
данная библиотека реализует анализ производительности выполняемого кода.

Использовать эти библиотеки можно двумя способами — указав имя библиотеки при линковке вашего кода (используя флаг -l), или загрузив ее с помощью LD_PRELOAD. Разработчики рекомендуют по возможности использовать первый метод, а второй метод использовать только если вы не имеете доступа к исходному коду.

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

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

Поиск утечек памяти

Поиск утечек памяти с помощью tcmalloc очень прост — надо слинковать программу с этой библиотекой, и запустить ее вот так:

# HEAPCHECK=normal ./your-program

или вот так (без линковки):

# LD_PRELOAD=/usr/lib/libtcmalloc.so.0.0.0 HEAPCHECK=normal ./your-program

и после выполнения программы, она выдаст отчет о найденных утечках памяти, например вот так:

# LD_PRELOAD=/usr/lib/libtcmalloc.so.0.0.0 HEAPCHECK=normal ./test-hashes 1000000

HeapChecker: Starting check "_main_"
HeapChecker: Ignoring 12 reachable objects of 275 bytes
.... Вывод программы .....
HeapChecker: Checking for whole-program memory leaks
HeapChecker: Ending check "_main_"
HeapChecker: Ignoring 32 reachable objects of 1679 bytes
HeapChecker: Heap memory leaks of 1000 bytes and/or 1 allocations detected by check "_main_".

HeapChecker: To investigate leaks manually use e.g.
cd /home/ott/projects/cpp-tests; /usr/bin/pprof ./test-hashes \
  "/tmp/test-hashes.2977._main_-end.heap"  \
  --inuse_objects --lines --edgefraction=1e-10 --nodefraction=1e-10 --gv 2>/dev/null

HeapChecker: Below is this pprof's output:

       1 100.0% 100.0%        1 100.0% main test-hashes.cpp:106
       0   0.0% 100.0%        1 100.0% 0xb7c8d450 ??:0
       0   0.0% 100.0%        1 100.0% _start ??:0


HeapChecker: crashing because of leaks
[1]    2977 segmentation fault (core dumped)  LD_PRELOAD=/usr/lib/libtcmalloc.so.0.0.0
               HEAPCHECK=normal ./test-hashes

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

Переменная среды HEAPCHECK указывает уровень проверок, которые будут применяться в процессе работы. Определено 4 значения для данной переменной — minimal, normal, strict и draconian — от самых простых, до все более изощренных проверок, использование которых конечно влияет на скорость работы анализируемой программы. Кроме этого, есть еще два режима: as-is — когда пользователь с помощью опций может задать список выполняемых проверок, и local — когда проверки выполняются только для кода, который явно отмечен для проверки (путем добавления вызовов функций GPT в исходный код программы).

При нахождении утечки памяти (как в нашем примере) библиотека аварийно завершает программу, но при этом выдает на экран стек вызовов функций, приведших к появлению утечки памяти. В нашем примере, утечка памяти происходит в функции main, на 106 строке кода в файле с исходным текстом (test-hashes.cpp).

В процессе работы библиотека учитывает значения следующих переменных среды (эти переменные определены для всех уровней проверок):

HEAP_CHECK_REPORT
(true или false, по умолчанию: true), определяет — выводить отчет на экран или нет;
HEAP_CHECK_STRICT_CHECK
(true или false, по умолчанию: true), определяет функцию, которая будет использоваться для проверок — SameHeap или NoLeaks;
HEAP_CHECK_IDENTIFY_LEAKS
(true или false, по умолчанию: false), позволяет получить адреса "потерянных" объектов;
HEAP_CHECK_TEST_POINTER_ALIGNMENT
(true или false, по умолчанию: false), проверяет все утечки памяти на предмет того, не могли ли они возникнуть из-за использования невыравненных указателей;
PPROF_PATH
определяет путь к программе pprof;
HEAP_CHECK_DUMP_DIRECTORY
определяет путь для временных файлов, используемых при работе библиотеки.

Дополнительную информацию о библиотеке и об использовании режимов as-is и local можно найти в данном документе.

Анализ потребления памяти

Кроме нахождения утечек памяти, библиотека tcmalloc позволяет производить анализ потребления памяти программами. Для выполнения данной задачи, библиотека отслеживает все выделения и освобождения блоков памяти. К отслеживаемым функциям выделения памяти относятся malloc, calloc, realloc и new.

Процедура использования библиотеки для анализа потребления памяти сходна с процедурой поиска утечек памяти, но отличается именами переменных среды. При работе в режиме анализа потребления памяти, библиотека выводит результаты в файл, указанный в переменной среды HEAPPROFILE, наличие которой и заставляет библиотеку работать в данном режиме. Например:

LD_PRELOAD=/usr/lib/libtcmalloc.so.0.0.0 HEAPPROFILE=gpt-heapprofile.log ./your-program

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

С помощью дополнительных переменных среды можно изменять поведение библиотеки, и например, заставить ее также анализировать вызовы mmap в дополнение к стандартным функциям выделения памяти (это происходит если переменную среды HEAP_PROFILE_MMAP установить в значение true).

Описание дополнительных переменных среды, а также примеры анализа данных, собранных библиотекой, вы сможете найти в документации.

Анализ производительности программ

Использование профайлера очень просто — надо лишь слинковать программу с библиотекой profiler, и указать имя файла куда будут выводиться собранные данные в переменной среды CPUPROFILE, например вот так:

# CPUPROFILE=/tmp/cpuprofile.log ./your-program

или можно вот так (без линковки библиотеки) — если вам нужно провести всего один анализ, или вы не имеете доступа к исходному коду программы:

# LD_PRELOAD=/usr/lib/libprofiler.so.0.0.0 CPUPROFILE=/tmp/cpuprofile.log ./your-program

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

После выполнения программы, собранные результаты оказываются в указанном вами файле, и вы можете провести их анализ. Для выполнения анализа используется программа pprof. Данные можно получать, как в текстовом:

23   2.4%  42.6%      309  32.4% std::less::operator

так и в графическом виде (это только часть графика, выводимого pprof):

При выводе результатов в виде текста, утилита выдает список функций, для каждой из которых указывается следующая информация (в колонке с соответствующим номером):

  1. количество проверок, проведенных в данной функции
  2. процентное отношение количества проверок для данной функции к общему количеству проверок
  3. процентное отношение количества проверок, проведенных до этого времени к общему количеству проверок
  4. количество проверок, проведенных в данной функции и всех функций, вызванных из нее
  5. процентное отношение количества проверок для данной функции и всех функций вызванных из нее к общему количеству проверок
  6. имя функции

При выводе в виде графика, кроме этой информации, показываются еще и зависимости между вызовами функции.

Более подробно об использовании cpu profiler и об анализе собранных результатов вы можете прочитать на сайте проекта, а про использование утилиты pprof читайте в следующем разделе.

Утилита pprof

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

pprof [необязательные опции] имя_программы имя_файла_с_результатами

Опции запуска утилиты можно разделить на общие, и специфичные для конкретных режимов работы. Общие опции позволяют указать формат выводимой информации, и степень подробности выводимой информации — опции --addresses, --lines, --functions (по умолчанию) или --files определят то, какой уровень подробности будет использоваться — физический адрес, строка кода, функция или файл с исходным текстом.

Утилита может выводить информацию как в текстовом (опция --text), так и в графическом виде (опции --gif, --ps, --pdf и другие). Можно также заставить ее вывести результаты в виде аннотированного исходного кода (опция --list), или дизассемблированного машинного кода (опция --disasm). Если утилита не получает опций, указывающий формат выводимой информации, то она переходит в режим интерактивной работы, где определены команды, соответствующие опциям командной строки (только без знаков --).

При проведении анализа данных, собранных во время анализа потребления памяти, определены опции, которые позволяют отображать количество используемых и/или выделенных объектов (--inuse_objects или --alloc_objects), объем выделенной памяти (--alloc_space) или использовать байты в качестве единицы измерения, вместо мегабайт, по умолчанию (опция --show_bytes).

При проведении анализа производительности программы, могут использоваться опции, определяющие подробность выводимой информации. Например, можно исключить из вывода объекты, соответствующие заданному регулярному выражению (--ignore), или можно управлять степенью детализации выводимых графиков (опции --nodecount, --nodefraction и --edgefraction).

Полное описание утилиты pprof можно найти в справочной странице, поставляемой вместе с исходными текстами, и устанавливаемой вместе с утилитой. А большее количество примеров можно найти на страницах, описывающих использование компонентов GPT.


1. Имеются правда некоторые особенности при сборке на 64-битных системах, о которых вы можете прочитать в файле INSTALL, входящем в архив с исходными текстами системы.

2. Для установки пакета на MS Windows вам необходимо скачать с сайта проекта специальную версию, которая содержит файлы проекта для сборки с помощью Visual C++. Дополнительную информацию можно найти в файле README.windows, входящем в состав исходных текстов.

3. Обе библиотеки могут без ограничений использоваться с многопотоковыми программами.

Last change: 05.03.2013 16:54

blog comments powered by Disqus