GLIBC: отладка утечек памяти: как интерпретировать вывод mtrace ()

Агрегирование по статусу и перекрестное присоединение к подзапросу с получением общего количества для расчета процента. Для переименования и пользовательского заказа вы можете использовать CASE с.

SELECT cs.s data,
       cs.c / ca.c * 100 value
       FROM (SELECT CASE client_status
                      WHEN 'BAD DEPT' THEN
                        1
                      WHEN 'ALERT' THEN
                        2
                      WHEN 'REMIND BAYAR' THEN
                        2
                      WHEN 'RUTIN BAYAR' THEN
                        4
                      WHEN 'POTENSI KOREKSI' THEN
                        5
                      WHEN 'TOP 10' THEN
                        6
                    END o,
                    CASE client_status
                      WHEN 'BAD DEPT' THEN
                        'Bad'
                      WHEN 'ALERT' THEN
                        'Alert'
                      WHEN 'REMIND BAYAR' THEN
                        'Remind'
                      WHEN 'RUTIN BAYAR' THEN
                        'Rutin'
                      WHEN 'POTENSI KOREKSI' THEN
                        'Potensi'
                      WHEN 'TOP 10' THEN
                        'Top'
                   END s,
                   count(*) c
                   FROM clients
                   GROUP BY client_status) cs
            CROSS JOIN (SELECT count(*) c
                               FROM clients) ca
       ORDER BY cs.o;
5
задан Eduard Wirch 30 September 2008 в 22:14
поделиться

4 ответа

Функция, которая выделяет память, вызывается несколько раз. Адрес вызывающей стороны указывает на код, который сделал выделение, и тот код просто выполняется несколько раз.

Вот пример в C:

void *allocate (void)
{
  return (malloc(1000));
}

int main()
{
  mtrace();
  allocate();
  allocate();
}

Вывод от mtrace:

Memory not freed:
-----------------
           Address     Size     Caller
0x0000000000601460    0x3e8  at 0x4004f6
0x0000000000601850    0x3e8  at 0x4004f6

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

Компиляция с флагами отладок (-g) полезна, если Вы можете:

Memory not freed:
-----------------
           Address     Size     Caller
0x0000000000601460    0x3e8  at /home/andrjohn/development/playground/test.c:6
0x0000000000601850    0x3e8  at /home/andrjohn/development/playground/test.c:6
5
ответ дан 18 December 2019 в 14:54
поделиться

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

Скомпилируйте свою сборку с отладкой на и выполните mtrace как такой:

$ gcc -g -o test test.c
$ MALLOC_TRACE=mtrace.out ./test
$ mtrace test mtrace.out

Memory not freed:
-----------------
   Address     Size     Caller
0x094d9378    0x400  at test.c:6

Вывод должен быть намного легче к обзору.

8
ответ дан 18 December 2019 в 14:54
поделиться

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

0
ответ дан 18 December 2019 в 14:54
поделиться

Одно возможное объяснение состоит в том, что та же функция выделяет различные буферные размеры? Одним таким примером является strdup.

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

Думайте об этом этот путь: в Java нет никаких деструкторов и никаких гарантий, что завершение будут когда-либо называть для любого объекта.

0
ответ дан 18 December 2019 в 14:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: