Как я могу найти утечку памяти запущенного процесса?

19

Есть ли способ, я могу найти утечку памяти запущенного процесса? Я могу использовать Valgrind для обнаружения утечек памяти перед началом процесса. Я могу использовать GDB, чтобы прикрепить его к запущенному процессу. Как я могу отладить утечки памяти запущенного процесса?

howtechstuffworks
источник
Valgrind очень полезен, я бы даже назвал его интуитивным.
user400344 15.07.16

Ответы:

13

Вот почти гарантированные шаги, чтобы найти, кто утечка памяти:

  1. Узнайте PID процесса, который вызывает утечку памяти.

    ps -aux
  2. захватить /proc/PID/smapsи сохранить в какой-то файл, как BeforeMemInc.txt.

  3. подождите, пока память не увеличится.
  4. захватить снова /proc/PID/smapsи сохранить егоafterMemInc.txt
  5. найти разницу между первым smapsи вторым smaps, например, с

    diff -u beforeMemInc.txt afterMemInc.txt

  6. запишите диапазон адресов, в котором увеличилась память, например:

       beforeMemInc.txt            afterMemInc.txt
    ---------------------------------------------------
    2b3289290000-2b3289343000   2b3289290000-2b3289343000  #ADDRESS
    Shared_Clean:    0 kB       Shared_Clean:    0 kB          
    Shared_Dirty:    0 kB       Shared_Dirty:    0 kB
    Private_Clean:   0 kB       Private_Clean:   0 kB
    Private_Dirty:  28 kB       Private_Dirty:  36 kB  
    Referenced:     28 kB       Referenced:     36 kB
    Anonymous:      28 kB       Anonymous:      36 kB  #INCREASE MEM
    AnonHugePages:   0 kB       AnonHugePages:   0 kB
    Swap:            0 kB       Swap:            0 kB
    KernelPageSize:  4 kB       KernelPageSize:  4 kB
    MMUPageSize:     4 kB       MMUPageSize:     4 kB
    Locked:          0 kB       Locked:          0 kB
    VmFlags: rd wr mr mw me ac  VmFlags: rd wr mr mw me ac
  7. используйте GDB для выгрузки памяти на работающий процесс или получите coredump, используя gcore -o process

  8. Я использовал gdb при запуске процесса для выгрузки памяти в какой-то файл.

    gdb -p PID
    dump memory ./dump_outputfile.dump 0x2b3289290000 0x2b3289343000
  9. Теперь используйте stringsкоманду или hexdump -Cраспечататьdump_outputfile.dump

    strings outputfile.dump
  10. Вы получаете читаемую форму, где вы можете найти эти строки в вашем исходном коде.

  11. Проанализируйте свой источник, чтобы найти утечку.

Джаганнатха Паттар
источник
12

Я думаю, что memleax это именно то, что вы хотите.

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

Работает на GNU / Linux и FreeBSD.

ПРИМЕЧАНИЕ: я автор, любое предложение приветствуется

== РЕДАКТИРОВАТЬ ==

Я пишу еще один инструмент libleak , который перехватывает функции памяти по LD_PRELOAD.

Также нет необходимости изменять целевую программу. Несмотря на то, что вам нужно перезапустить процесс с LD_PRELOAD, вы можете включить / отключить обнаружение во время работы.

Там гораздо меньше влияния на производительность, так как нет ловушки сигнала.

По сравнению с аналогичными инструментами (такими как mtrace), он печатает полный стек вызовов в подозрительной точке утечки памяти.

Бинчжэн Ву
источник
1
Я ручаюсь за memleax как очень полезный инструмент для отслеживания любых очевидных утечек. В выходные резюме удивительно эффективны . Почти как я написал бы их, если бы у меня была вычислительная мощность, чтобы сделать это вручную. Спасибо за это
сэх
6

В Linux вы можете включить mtrace в своей программе, но это изменение кода.

В OpenBSD вы можете попробовать статистику malloc .

Также стоит взглянуть на программу проверки утечек Google , и в отличие от mtrace вы можете использовать ее, LD_PRELOADчтобы избежать перекомпиляции.

Бесполезный
источник
0

Я думаю, что без поддержки мониторинга распределения после запуска программы непосредственно в исходном коде, вам не повезло. Вот две причины, которые я могу придумать:

  • Проверка кучи инициализируется при запуске программы. Некоторые предлагают возможность точной настройки времени, но переменные среды, которые их запускают, должны быть установлены при запуске программы. Это потому, что они следят за тем, чтобы убедиться, что каждому выделению соответствует соответствующее освобождение, и в противном случае они будут пропускать некоторые.
  • Проверка кучи обычно требует повышенных привилегий или хуков, предоставляемых операционной системой. Если эти хуки не предоставляются во время запуска программы, средства проверки кучи не могут их использовать. Я не верю, что ОС предоставляют эти привилегии после запуска рассматриваемой программы.

Однако, если ваша программа выполняется внутри виртуальной машины, эта среда может обеспечить поддержку распределения ресурсов. Я знаю, что в Java есть несколько инструментов для выделения и мониторинга сборки мусора (например, visualVM ), которые подключаются к работающим программам или виртуальным машинам.

Крис Бетти
источник
0

Purify от IBM, вероятно, самый старый и самый сложный инструмент из всех. Он будет отмечать номер строки в коде, который вызывает утечку памяти.

жизненный баланс
источник