LINUX.ORG.RU

valgrind показывает завышенный объем памяти

 ,


1

3
==10810== HEAP SUMMARY:
==10810==     in use at exit: 0 bytes in 0 blocks
==10810==   total heap usage: 302,283 allocs, 302,283 frees, 221,555,789 bytes allocated

Реально запрошено 35644320 байт (без учета накладных расходов).

Это 95000 объектов по 48 байт + 95000 объектов по 128 + 95000 объектов по 192 байта + еще 1Mb

Там правда еще есть realloc() который прошел c 1600 байт до 758400 с шагом 1600 байт :(

правильный time -v говорит «Maximum resident set size (kbytes): 41220»

Если запустить «time -v valgrind ./prog» то получаем «Maximum resident set size (kbytes): 147480»

Откуда такая адская цифра в valgrind?

Если я не освобождаю память, то все еще интереснее

==18447== HEAP SUMMARY:
==18447==     in use at exit: 35,691,280 bytes in 284,109 blocks
==18447==   total heap usage: 302,283 allocs, 18,174 frees, 221,555,789 bytes allocated
==18447==
==18447== LEAK SUMMARY:
==18447==    definitely lost: 112 bytes in 1 blocks
==18447==    indirectly lost: 805,248 bytes in 2 blocks
==18447==      possibly lost: 0 bytes in 0 blocks
==18447==    still reachable: 34,885,920 bytes in 284,106 blocks

Да! Я не отдал 34,885,920 байт! Но откуда 220М мегабайт ?!

★★★★★

откуда 220М мегабайт ?!
realloc() который прошел c 1600 байт до 758400 с шагом 1600 байт :(

Не? Valgrind же говорит не Maximum resident set size, а сумму всех аргументов переданных в malloc(), поэтому она и не меняется, если ничего не освобождать.

xaizek ★★★★★
()

Даже без чтения документации видно что allocated - это просто сумма всех аллокаций.

slovazap ★★★★★
()

Есть подозрение, что оно считает некоторые области mmap()

glibc частенько просит 3x64Mb через mmap и без прав rwx (---p)

vel ★★★★★
() автор топика
Ответ на: комментарий от vel

glibc частенько просит 3x64Mb через mmap

По 64 МБ на каждую нить. Но не припомню, чтобы Valgtind считал это аллокацией. Он отслеживает на границе вызовов malloc, free и подобных.

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от i-rinat

на эту же программу, в которой в main() сразу же делается exit(0) valgrind сразу говорит 32Мб

Программа без тредов и внешних библиотек.

Есть подозрение, что это «цена» работы valgrind, иначе как он отслеживает нарушение записи за предел выделенного участка ? (720 байт на каждый alloc()?)

Очень нехорошей особенностью работы тестируемой программы является выделение большого числа мелких структур как фиксированного размера (48,128,144 байт), так и произвольного через realloc().

Я сейчас раздумываю как бы это в ядро запихнуть и максимально использовать возможности slab.

vel ★★★★★
() автор топика
Ответ на: комментарий от vel

это «цена» работы valgrind

Сильно вряд ли. Он знает, сколько запрошено памяти, поэтому реально может выделить больше для создания красных зон вокруг. Точно так же он точно знает, сколько памяти освобождается. Зачем ему в такой ситуации включать в отчёт служебные аллокации? Это не имеет смысла.

на эту же программу, в которой в main() сразу же делается exit(0) valgrind сразу говорит 32Мб

Поищи в программе функции с __attribute__((constructor)), статические объекты C++ и аналогичные вещи в библиотеках, к которым линкуешься. Убедись, что не подгружается что-нибудь через LD_PRELOAD.

Кстати, вызов mmap с MAP_ANONYMOUS не считается Valgrind'ом за аллокацию. По крайней мере, Memcheck'ом. У Massif есть для этого специальная опция: --pages-as-heap.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Сильно вряд ли. Он знает, сколько запрошено памяти, поэтому реально может выделить больше для создания красных зон вокруг. Точно так же он точно знает, сколько памяти освобождается. Зачем ему в такой ситуации включать в отчёт служебные аллокации? Это не имеет смысла.

да, действительно, смысла в этом нет.

Поищи в программе функции с __attribute__((constructor)), статические объекты C++ и аналогичные вещи в библиотеках, к которым линкуешься. Убедись, что не подгружается что-нибудь через LD_PRELOAD.

Это старинный С проект, там нет ничего хитрого. LD_PRELOAD пуст.

Это одна из реализаций алгоритма Ахо - Корасик написанного на чистом C.

Похоже есть разгадка.

valgrind странно считает realloc()!

Есть область 1600 байт, которая 475 раз расширяется на 1600 байт (результат 760кб).

Если не считать память освобожденной, этот как раз 180Мб + 34Мб размер полученной структуры это ~210Мб

vel ★★★★★
() автор топика
Ответ на: комментарий от vel

valgrind странно считает realloc()!

Realloc можно считать комбинацией malloc+memcpy+free. Более того, его даже логично таким считать.

Запуск под Valgrind поменяет поведение realloc(), потому что запрашиваться будут блоки большего размера — нужно же где-то красные зоны размещать. Потенциально, он может проверять, поменялся ли указатель, и в зависимости от этого считать по-разному. Но зачем? Это всё равно не будет отражать поведение программы, запущенной вне Valgrind. И числа от запуска к запуску тогда могут получаться разными, что приведёт к ещё большим недоразумениям.

Кстати, если хочешь проверять использование памяти, лучше пользоваться Massif. Тебе ведь вряд ли нужно знать сумму всех аллокаций за время работы. Наверняка важнее знать суммарный объём в зависимости от времени.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Я уменьшил число realloc() и итог такой

==24813==   total heap usage: 301,820 allocs, 301,820 frees, 36,744,957 bytes allocated

Теперь все стало понятно.

vel ★★★★★
() автор топика
Последнее исправление: vel (всего исправлений: 1)
Ответ на: комментарий от vel

Ахо - Корасик

Стоит ещё глянуть на другие алгоритмы. Кажется, это сейчас уже не самый эффективный способ искать строки.

i-rinat ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.