как выследить утечку памяти, которую валгринд говорит, не существует?
У меня есть программа, которая принимает данные из сокета, выполняет некоторый контроль качества и сортирует другие условия к нему, а затем записывает его в именованный канал. Я запустил valgrind и исправил все утечки памяти, которые изначально существовали. Затем я создал "демонстрационную" среду в системе, где у меня было 32 экземпляра этой программы, каждый из которых подавал уникальные данные и каждый выводил в свой собственный канал. Мы протестировали его, и все выглядело нормально. Затем я попробовал стресс-тестирование, повысив скорость, с которой данные отправляются с абсурдной скоростью, и все сначала выглядело хорошо...но мои программы продолжали потреблять все больше и больше памяти, пока у меня не осталось ресурсов.
Я повернулся к valgrind и запустил точно такую же настройку, за исключением каждой программы, запущенной внутри valgrind, используя leak-check=full. Произошло несколько странных вещей. Во-первых, память действительно протекала, но только до той точки, где каждая программа потребляла .9 % моей памяти (ранее самый большой боров памяти имел полный 6% моего память.) С valgrind, работающим на CPU, стоимость программ взлетела, и теперь я был на 100% cpu с огромной средней нагрузкой, поэтому, возможно, отсутствие доступного процессора заставило программы работать достаточно медленно, что утечка заняла слишком много времени, чтобы проявиться. Когда я попытался остановить эти программы, valgrind не показал прямых утечек памяти, он показал некоторые потенциальные утечки памяти, но я проверил их, и я не думаю, что какие-либо из них представляют собой реальные утечки памяти; и кроме того, возможная утечка памяти только показала как несколько килобайт, в то время как программа потребляла более 100 МБ. Доступная (не утечка) память, сообщенная valgrind, также находилась в диапазоне КБ, поэтому valgrind, похоже, считает, что мои программы потребляют часть памяти, которую Top говорит, что они используют.
Я запустить несколько тестов и получил странные результаты. Одна-единственная программа, даже работающая втрое быстрее, чем была обнаружена моя первоначальная утечка памяти, никогда не потребляет больше .9% памяти, две программы утечка до 1.9 и 1.3% памяти соответственно, но не более и т. д., Это как если бы объем памяти просочился, и скорость, с которой он протекает, каким-то образом зависит от того, сколько экземпляров моей программы запущено за один раз; что не имеет смысла, каждый экземпляр должен быть 100% независимым от других.
Я также нашел, если я запускаю 32 экземпляра только с одним экземпляром, запущенным в valgrind valgrinded instance (это слово, если я говорю, что это!) утечки памяти, но с более медленной скоростью, чем те, которые работают за пределами с Valgrind. Экземпляр valgrind все равно скажет, что у меня нет прямых утечек и сообщает о гораздо меньшем потреблении памяти, чем показывает Top.
Я довольно озадачен тем, что может быть причиной этого результата, и почему валгринд отказывается знать об утечке памяти. Я думал, что это может быть внешняя библиотека, но на самом деле я не использую внешние библиотеки; только основные функции/объекты c++. Я также считал, что это могут быть данные, записанные в выходной канал, чтобы быстро вызвать рост буфера бесконечно, но 1) должен быть верхний предел, что такой буфер может расти и 2) после утечки памяти, если я сброшу скорость ввода данных в ничто, память остается потребленной, а затем медленно падает до разумного количества.
может кто-нибудь дать мне подсказку, где я должен искать здесь? Я совершенно не понимаю, почему память ведет себя таким образом.
спасибо.
3 ответов
Это звучит как проблема, которую я имел недавно.
Если ваша программа принимает данные и буферизует их внутри без каких-либо ограничений, то она может считывать и буферизировать быстрее, чем она может выводить данные. В этом случае использование памяти будет продолжать увеличиваться без ограничений.
чем больше экземпляров программы, которую вы запускаете, тем медленнее каждый экземпляр будет идти, и тем быстрее буферы будут увеличиваться.
Это может быть или не быть вашей проблемой, но без более это лучшее, что я могу сделать.
вы должны сначала искать мягкую утечку. Это происходит, когда какой-то статический или синглтон постепенно увеличивает какой-то буфер или контейнер и собирает в него мусор. Технически это не утечка, но ее последствия так же плохи.
могу я предложить вам попробовать с MemoryScape? Этот инструмент делает довольно хорошую работу в обнаружении утечки памяти. Это не бесплатно, но учитывая потраченное время и энергию, стоит попробовать.