Найти memory leak
От: Аноним  
Дата: 27.09.13 07:22
Оценка:
Собственно, сабж. Есть приложение, в процессе работы которого количество использованной памяти стабильно и неуклонно растет (платформа — Linux).
Задача осложняется тем, что утечек в обычном смысле нет: мемчекер по окончании работы не показывает потерянных указателей и утечек, т.е. по окончании все корректно освобождается. Прога обрабатывает файлы. То есть полный цикл алгоритма состоит из обработки одного файла, по окончании цикла количество использованной памяти должно равняться ее количеству до входа в цикл. Но, похоже, где-то забываю почистить какую-то динамическую структуры. Как такое отлавливать?
Re: Найти memory leak
От: jazzer Россия Skype: enerjazzer
Дата: 27.09.13 07:50
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Собственно, сабж. Есть приложение, в процессе работы которого количество использованной памяти стабильно и неуклонно растет (платформа — Linux).

А>Задача осложняется тем, что утечек в обычном смысле нет: мемчекер по окончании работы не показывает потерянных указателей и утечек, т.е. по окончании все корректно освобождается. Прога обрабатывает файлы. То есть полный цикл алгоритма состоит из обработки одного файла, по окончании цикла количество использованной памяти должно равняться ее количеству до входа в цикл. Но, похоже, где-то забываю почистить какую-то динамическую структуры. Как такое отлавливать?

Отключать (заменить на заглушки) функциональность по кусочкам, пока утечка не прекратится, потом начать добавлять обратно, пока не появится опять.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Найти memory leak
От: wvoquine  
Дата: 27.09.13 08:03
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Собственно, сабж. Есть приложение, в процессе работы которого количество использованной памяти стабильно и неуклонно растет (платформа — Linux).

А>Задача осложняется тем, что утечек в обычном смысле нет: мемчекер по окончании работы не показывает потерянных указателей и утечек, т.е. по окончании все корректно освобождается. Прога обрабатывает файлы. То есть полный цикл алгоритма состоит из обработки одного файла, по окончании цикла количество использованной памяти должно равняться ее количеству до входа в цикл. Но, похоже, где-то забываю почистить какую-то динамическую структуры. Как такое отлавливать?


В смысле, вся выделенная в цикле память освобождается, и Linux, типа, должен сделать sbrk назад?

А что по этому поводу думают библиотеки, которыми ты пользуешься, освобождают ли они свою память, в чем я сомневаюсь
To be is to be the value of a variable
Re[2]: Найти memory leak
От: wvoquine  
Дата: 27.09.13 08:06
Оценка:
Здравствуйте, wvoquine, Вы писали:

W>А что по этому поводу думают библиотеки, которыми ты пользуешься, освобождают ли они свою память, в чем я сомневаюсь



В частности, чтение из файла.
To be is to be the value of a variable
Re: Найти memory leak
От: Vzhyk  
Дата: 27.09.13 08:12
Оценка:
27.09.2013 10:22, Аноним 24 пишет:

> То есть

> полный цикл алгоритма состоит из обработки одного файла, по окончании
> цикла количество использованной памяти должно равняться ее количеству до
> входа в цикл.
Вообще-то не должно и не будет.
А как искать, jazzer уже написал.
Posted via RSDN NNTP Server 2.1 beta
Re: Найти memory leak
От: Evgeny.Panasyuk Россия  
Дата: 27.09.13 11:30
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как такое отлавливать?


Другой вариант — вместо отключения сделать scope-based memory usage/delta print. Вот таким образом:
{
    {
        MemUsageDelta foo("Part 1");
        part1();
    }
    {
        // Or as macro:
        MEM_USAGE_DELTA("Part 2");
        part2();
    }
}

В конструкторе будет запоминаться текущее использование, а в деструкторе дельта пойдёт в log.
Для этого необходимо сделать свои operator new/new[], delete/delete[] (или что там у вас используется для аллокаций) + unordered_map для размеров — всего получается меньше ста строк.
Если есть такие проблемы, то можно сделать даже assert-like чтобы сразу их ловить:
{
    ASSERT_MEM_USAGE_DELTA_ZERO("Part X");
    part_x();
}


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

P.S. И в случае отключения кусочков, как посоветовали выше, и в случае мониторинга — не забываем про бинарный поиск.
Re[2]: Найти memory leak
От: Vzhyk  
Дата: 27.09.13 11:42
Оценка:
27.09.2013 14:30, Evgeny.Panasyuk пишет:

> Для этого необходимо сделать свои operator new/new[], delete/delete[]

> (или что там у вас используется для аллокаций) + unordered_map для
> размеров — всего получается меньше ста строк.
Но там могут и малоки и другие запросы на выделение памяти.
Это все хорошо, если есть гарантия, что только new и delete. В более ни
менее сложных проектах на это закладываться опасно — время потратишь, а
выхлоп нулевой, имхо то, что написал jazzer универсальные и правильнее.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Найти memory leak
От: Evgeny.Panasyuk Россия  
Дата: 27.09.13 11:59
Оценка:
Здравствуйте, Vzhyk, Вы писали:

>> Для этого необходимо сделать свои operator new/new[], delete/delete[]

>> (или что там у вас используется для аллокаций) + unordered_map для
>> размеров — всего получается меньше ста строк.
V>Но там могут и малоки и другие запросы на выделение памяти.
V>Это все хорошо, если есть гарантия, что только new и delete.

Естественно.
Re[3]: Найти memory leak
От: wvoquine  
Дата: 27.09.13 12:10
Оценка:
Здравствуйте, Vzhyk, Вы писали:

V>27.09.2013 14:30, Evgeny.Panasyuk пишет:


V>Но там могут и малоки и другие запросы на выделение памяти.

V>Это все хорошо, если есть гарантия, что только new и delete. В более ни
V>менее сложных проектах на это закладываться опасно — время потратишь, а
V>выхлоп нулевой, имхо то, что написал jazzer универсальные и правильнее.


Да, точно там буфер для чтения из файла увеличивается и фрагментирует память. Потом ее не удается по-старому на новой итерации упаковать приходится двигаться дальше...

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

Конечно же, мы тут не предполагаем, что там какие-нибудь уже ненужные векторы вроде как освобождаются, а зарезервированную память еще держат.
To be is to be the value of a variable
Re[4]: Найти memory leak
От: Vzhyk  
Дата: 27.09.13 12:17
Оценка:
27.09.2013 15:10, wvoquine пишет:

> Да, точно там буфер для чтения из файла увеличивается и фрагментирует

> память. Потом ее не удается по-старому на новой итерации упаковать
> приходится двигаться дальше...
Это странно, если вы сами не запрашиваете читать, все большие блоки
памяти, причем так, чтобы вся цепочка "менеджеров памяти" это не с
амортизировала. Обычно в какой-то момент приложение выходит на некий
объем памяти и потребление находится около него (что-то по мелочи
освобождается, что-то захватывается).
Posted via RSDN NNTP Server 2.1 beta
Re[5]: Найти memory leak
От: wvoquine  
Дата: 27.09.13 12:26
Оценка:
Здравствуйте, Vzhyk, Вы писали:

V>Это странно, если вы сами не запрашиваете читать, все большие блоки

V>памяти, причем так, чтобы вся цепочка "менеджеров памяти" это не с
V>амортизировала. Обычно в какой-то момент приложение выходит на некий
V>объем памяти и потребление находится около него (что-то по мелочи
V>освобождается, что-то захватывается).


Да мы ведь и не знаем, в чем задача вообще состоит и даже на каком языке написана.

Но по описанию автора — в обычном смысле утечек нет, но он удивляется, что память все же растет от итерации к итерации.
Так вот интересно, насколько растет — есть там вообще тема для дискуссии, в первую очередь.

Во-вторых, насколько долго оно растет... Так то оно, может, и стабилизируется.
To be is to be the value of a variable
Re: Найти memory leak
От: ilnar Россия  
Дата: 27.09.13 18:25
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Собственно, сабж. Есть приложение, в процессе работы которого количество использованной памяти стабильно и неуклонно растет (платформа — Linux).

А>Задача осложняется тем, что утечек в обычном смысле нет: мемчекер по окончании работы не показывает потерянных указателей и утечек, т.е. по окончании все корректно освобождается. Прога обрабатывает файлы. То есть полный цикл алгоритма состоит из обработки одного файла, по окончании цикла количество использованной памяти должно равняться ее количеству до входа в цикл. Но, похоже, где-то забываю почистить какую-то динамическую структуры. Как такое отлавливать?

Если у тебя в конце все освобождается, возможно, программа ведет учет выделенного как-то и потом удаляет, поэтому на выходе формально нет утечек,
а вот в каких-то частях код забывает о чем-то выделенном, и выделяет дальше снова и снова.
Поэтому надо смотреть отдельные участкие, встрой в места, где на входе и выходе должно быть одинаково, специальный код от tcmalloc, и скомпиляйся с ним.
Потом запусти работать. http://google-perftools.googlecode.com/svn/trunk/doc/heap_checker.html
Re: Найти memory leak
От: vladimir_i СССР  
Дата: 28.09.13 10:54
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Собственно, сабж. Есть приложение, в процессе работы которого количество использованной памяти стабильно и неуклонно растет (платформа — Linux).

А>Задача осложняется тем, что утечек в обычном смысле нет: мемчекер по окончании работы не показывает потерянных указателей и утечек, т.е. по окончании все корректно освобождается. Прога обрабатывает файлы. То есть полный цикл алгоритма состоит из обработки одного файла, по окончании цикла количество использованной памяти должно равняться ее количеству до входа в цикл. Но, похоже, где-то забываю почистить какую-то динамическую структуры. Как такое отлавливать?

Можно запустить через dbx (или другой доступный отладчик):

>dbx <им программы>
dbx>runargs <параметры>
dbx>check -memuse или check -leaks или check -all
dbx>run
...


Возможно, результат наведет на какие-нибудь мысли.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.