JEMALLOC

Материал из Home Wiki
Перейти к навигации Перейти к поиску

https://access.redhat.com/solutions/61334

Introduction

Детектирование утечек памяти может быть сложной задачей, если нет воспроизводимого тестового сценария и, следовательно, детектирование их в производственной среде может вызывать связанные с этим проблемы со скоростью выполнения из-за значительного накладного затраты традиционных инструментов обнаружения утечек памяти, таких как Valgrind. Используя другой подход к профилированию и обнаружению утечек памяти, JEMALLOC может быть использован в производственных средах без значительной потери производительности. В этой статье объясняется, как использовать библиотеку пользовательского уровня JEMALLOC для распределения памяти для обнаружения утечек памяти в контексте Red Hat Directory Server 11 и процесса сервера ns-slapd. Описанная техника может быть применена к любому процессу, который либо связан с JEMALLOC или загружен.

Как это работает

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

Как настроить

Red Hat Directory Server 11 уже поставляется с JEMALLOC установленным и включенным по умолчанию. Однако по умолчанию все функции профилирования отключены. Чтобы включить профилирование памяти и обнаружение утечек в частности, редактируйте файл конфигурации systemd Directory Server

/etc/systemd/system/dirsrv@.service.d/custom.conf

или если установлено более одного экземпляра и вы хотите целевую настройку конкретного экземпляра, используйте конфигурацию на уровне экземпляра вместо этого

/etc/systemd/system/dirsrv@<instance>.service.d/custom.conf

Добавьте следующие параметры конфигурации JEMALLOC MALLOC_CONF

[Service]

TimeoutStartSec=0
TimeoutStopSec=600

Environment=MALLOC_CONF=prof:true,prof_leak:true,lg_prof_sample:19,prof_final:true,stats_print:true,prof_prefix:/run/dirsrv/jeprof
Environment=LD_PRELOAD=/usr/lib64/dirsrv/lib/libjemalloc.so.2

Эти параметры конфигурации JEMALLOC говорят о том, что

 * Включить профилирование и обнаружение утечек.
 * Использовать выборочное профилирование размером 2^19 байт.
 * Генерировать профиль при выходе процесса.
 * Печатать внутренние статистики аллокатора.
 * Сохранять данные профиля в каталоге /run/dirsrv.

Чтобы применить эту конфигурацию к процессу Directory Server, выполните

# systemctl daemon-reload
# systemctl restart dirsrv@<instance>

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

Как профильтровать

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

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

lg_prof_sample:19

является стандартной периодичностью выборочного профилирования 2^19 байт (512 Кб), которая подходит в большинстве случаев, поскольку она достигает хорошего баланса между точностью и производительностью. Уменьшение этого значения приведет к более частому выборочному профилированию, а увеличение — к режиму выборочного профилирования с меньшей частотой. Каждый выборочный профиль берется после выделения памяти, указанного в значении. Для серверных приложений с большим объемом памяти, которые часто выделяют память в ответ на активность клиентов, значение по умолчанию приведет к тому, что будет сделано достаточно выборок для того, чтобы поймать наиболее существенные утечки памяти.

Сбор данных

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

/run/dirsrv/jeprof.2613573.0.f.heap

Внутренние статистики аллокатора и резюме утечки памяти будут отдельно логироваться через syslog

/var/log/messages:

___ Begin jemalloc statistics ___
[ ... ]
--- End jemalloc statistics ---

ns-slapd[2613573]: <jemalloc>: Leak approximation summary: ~2966192 bytes, ~22 objects, >= 5 contexts
ns-slapd[2613573]: <jemalloc>: Run jeprof on "/run/dirsrv/jeprof.2613573.0.f.heap" for leak detail

Данные профиля вместе с сообщениями syslog можно либо отправить напрямую в Red Hat Support для дальнейшего анализа и/или преобразовать в отчет о профилировании и проанализировать локально. Обсуждение того, как анализировать утечки памяти, находится за пределами темы этой статьи.

Локальные отчеты

Чтобы создать отчет на основе данных профиля, требуется инструмент jeprof. Этот инструмент обычно является частью поставки Directory Server 11 и можно найти в следующем месте

/usr/lib64/dirsrv/bin/jeprof

Также он может быть получен из GitHub-страницы JEMALLOC upstream, если это необходимо.

Примечание. Чтобы сгенерировать значимые отчеты jeprof требует пакетов debuginfo для всех исполняемых файлов и библиотек, которые профилируются. Это требуется для сопоставления данных профиля, собранных для развертывания стека вызова и связанных с этим целей. Для Directory Server они

389-ds-base-debuginfo
389-ds-base-libs-debuginfo

Эти пакеты можно установить с помощью следующей команды:

debuginfo-install 389-ds-base

С этими пакетами в наличии jeprof инструмент может быть использован для создания и проверки отчетов на основе данных профиля, собранных. Однако если утечка памяти возникает за пределами Directory Server кода базы, например, в одной из связанных библиотек, то пакеты debuginfo для этих также должны быть установлены.

jeprof --show_bytes /usr/sbin/ns-slapd /run/dirsrv/jeprof.2613573.0.f.heap
    Using local file /usr/sbin/ns-slapd.
Using local file /run/dirsrv/jeprof.2613573.0.f.heap.
Welcome to jeprof!  For help, type 'help'.
(jeprof) top
Total: 2998001 B
  829411  27.7%  27.7%   829411  27.7% slapi_ch_malloc
  592551  19.8%  47.4%   592551  19.8% sqlite3_errmsg
  527365  17.6%  65.0%   527365  17.6% PORT_ZAlloc_Util
  524368  17.5%  82.5%   524368  17.5% slapi_ch_calloc
  524304  17.5% 100.0%   524304  17.5% __GI___strdup
       0   0.0% 100.0%  1119917  37.4% C_GetInterface
       0   0.0% 100.0%   592551  19.8% NSS_Initialize
       0   0.0% 100.0%   592551  19.8% NSS_IsInitialized
       0   0.0% 100.0%   527365  17.6% PK11_FreeSymKey
       0   0.0% 100.0%   527365  17.6% PK11_PubUnwrapSymKeyWithFlagsPerm
(jeprof)

Инструмент jeprof имеет ряд вариантов отчетов и форматов, но обсуждение этих находится за пределами темы этой статьи. Вне доступной документации Red Hat Support может посоветовать по вопросам профилирования и создания отчетов в зависимости от конкретных сценариев использования и требований.