Как обнаружить утечку памяти?


16

Кажется, у меня большая утечка памяти в моей текущей системе Ubuntu

После сообщения о странных ошибках памяти Eclipse ( /ubuntu/148998/eclipse-constant-different-out-of-memory-errors ) я начал получать сообщения об ошибках «недостаточно памяти» в своей консоли сегодня - пока делать простые задачи, такие как ввод sudo -s- или даже -free -m

Набрав в 'free -m', я убедительно показал, как быстро увеличивается объем ОЗУ с 700 до 900 МБ, а за несколько секунд вырос до 2000 М (после освобождения памяти с помощью echo 3 > /proc/sys/vm/drop_caches).

Затмение - не причина, я полностью убил процесс, и баран все еще шел. Есть ли способ определить, откуда происходит утечка? Я даже больше apt-get updateне могу обновить свою систему, так как происходит сбой (возможно, потому что не хватает памяти)

С помощью Ubuntu 11.10


Я ОЧЕНЬ счастлив, что я не сумасшедший. У меня была такая же проблема с момента обновления до 13.10, но я помню, что с 11.10. Вопрос в том, используете ли вы CrashPlan? Мне кажется, что это сузилось, я просто не знаю, как это исправить. Я пробовал настройки памяти, но это не работает. Я надеюсь, что это даст вам некоторые подсказки
полу-новичок

Нет смысла заставлять ядро ​​удалять кэши. Они будут сброшены, и их пространство будет восстановлено в любом случае, как только потребуется больше физической памяти. Принудительная очистка их, скорее всего, даже наносит ущерб общей производительности, поскольку некэшированные объекты необходимо извлекать из гораздо более медленного вторичного хранилища. Свободная основная память ни в коем случае не хорошая вещь. Это либо признак плохого управления кешем, либо очень легкого использования.
Дэвид Фёрстер,

Ответы:


9

Memprof - это инструмент для профилирования использования памяти и обнаружения утечек памяти. Он может генерировать профиль, сколько памяти было выделено каждой функцией в вашей программе. Кроме того, он может сканировать память и находить блоки, которые вы выделили, но на которые больше нет ссылок.

Memprof работает путем предварительной загрузки библиотеки, чтобы переопределить функции выделения памяти библиотеки C, и не требует перекомпиляции вашей программы.

memprof

Источник: Руководство по Ubuntu


11

Во-первых, убедитесь, что у вас есть временная папка, в которой достаточно свободного места. Следующие команды создают дампы размером несколько ГБ.

Вы можете создать новую папку tmp, используя следующую команду. Вы можете перейти /tmpна другую файловую систему с достаточным пространством

TMPDIR=$(mktemp -d -t -p /tmp)

Шаги, чтобы найти утечку памяти

  1. Узнайте PID процесса, который вызывает утечку памяти (вы также можете использовать, например, htopесли доступно) и сохранить его в переменной с именемpid

    ps -aux
    
  2. Учитывая, что PID доступен в переменной pid, вы можете зафиксировать потребление памяти с помощью /proc/$pid/smapsи сохранить в некоторый файл, например beforeMemInc.txt.

    cat /proc/$pid/smaps > $TMPDIR/beforeMemInc.txt
    
  3. Подождите некоторое время, чтобы потребление памяти увеличилось.
  4. Захватите /proc/$pid/smapsснова и сохраните какafterMemInc.txt

    cat /proc/$pid/smaps > $TMPDIR/afterMemInc.txt
    
  5. Найдите разницу между первым smapsи вторым smaps, например, с помощью

    diff -u $TMPDIR/beforeMemInc.txt $TMPDIR/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 $TMPDIR/process $PID
    
  8. Я использовал gdb в запущенном процессе, чтобы записать память в какой-нибудь файл.

    cd $TMPDIR
    gdb -p $pid
    dump memory memory.dump 0x2b3289290000 0x2b3289343000
    
  9. Теперь используйте stringsкоманду или, hexdump -Cчтобы напечататьmemory.dump

    strings memory.dump
    

    Из этого вы получите читаемую информацию, которая поможет вам найти эти строки в вашем исходном коде.

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

Я нахожусь в контейнере Docker, получая ошибку «Отказано в доступе» при выполнении cat /proc/2882/smaps > /tmp/before.txtна шаге 2. Что я сделал не так?
Деви

8

Трюк drop_cache не освободит память, он сбросит кеш. Использует команду ps, если вы хотите определить, какие процессы используют больше памяти.

Например, чтобы следить за списком 15 лучших пользователей резидентной памяти.

$ watch "ps --sort -rss -eo pid,pmem,rss,vsz,comm | head -16"
  PID %MEM   RSS    VSZ COMMAND
 2590 13.4 136892 825000 firefox
 1743 10.7 109020 300780 Xorg
 2067  8.5 86764 1118140 unity-2d-shell
 3307  4.1 42560 627780 unity-2d-spread
 2068  2.9 29904 617644 unity-2d-panel
 2092  2.5 25524 1291204 nautilus
 2457  1.9 20292 530276 gnome-terminal
 2351  1.9 20016 821488 unity-scope-vid
 2161  1.9 19476 531968 unity-panel-ser
 2034  1.7 18256 759716 gnome-settings-
 2074  1.5 16176 518016 nm-applet
 2273  1.5 15452 580416 unity-lens-vide
 2051  1.4 15112 524260 metacity
 2395  1.2 12836 407336 update-notifi

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

Распределение Pmap:

$ ls -l /run/shm
total 272
-r-------- 1 ed      ed      67108904 Nov 29 18:17 pulse-shm-1884617860
-r-------- 1 lightdm lightdm 67108904 Nov 29 18:11 pulse-shm-2352897759
-r-------- 1 ed      ed      67108904 Nov 29 18:12 pulse-shm-3444873503
-r-------- 1 ed      ed      67108904 Nov 29 18:12 pulse-shm-3485341848
-r-------- 1 lightdm lightdm 67108904 Nov 29 18:11 pulse-shm-535843976
-r-------- 1 ed      ed      67108904 Nov 29 19:12 pulse-shm-789046959
-r-------- 1 ed      ed      67108904 Nov 29 18:38 pulse-shm-863909656

$ df /run/shm 
Filesystem     1K-blocks  Used Available Use% Mounted on
none              509332   272    509060   1% /run/shm

обратите внимание, что зарезервированные выделения намного выше, чем реальные выделенные страницы (df 'used')

Распределение системы V:

$ ipcs -m 

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x00000000 294912     ed         700        122880     2          dest         
0x00000000 327681     ed         700        4823040    2          dest         
0x00000000 491522     ed         600        393216     2          dest         
0x00000000 589827     ed         700        4578120    2          dest         
0x00000000 425988     ed         700        27852      2          dest         
0x00000000 458757     ed         600        393216     2          dest         

Изменить : необходимо перейти --sort -rssк, psчтобы получить процессы с наибольшим использованием памяти, в противном случае список процессов сортируется по возрастанию численных и дает процессам с наименьшим использованием памяти.


5

У меня есть старая машина, которую я использую, которая постоянно выдает сообщения об утечке памяти:

root@:~# free -m
             total       used       free     shared    buffers     cached
Mem:          1898       1523        374        131         32        588
-/+ buffers/cache:        902        995
Swap:         1942        480       1462

Мой сценарий:

sync; sudo echo 3 > /proc/sys/vm/drop_caches

Назвал это cache.sh

root@~# ./cache.sh
root@~# free -m
             total       used       free     shared    buffers     cached
Mem:          1898       1106        791        126          1        207
-/+ buffers/cache:        897       1000
Swap:         1942        480       1462

Вы можете видеть, что я сократился до 374 МБ, побежал sync; sudo echo 3 > /proc/sys/vm/drop_cachesи получил 417 МБ обратно. Можно cronзапустить его каждые 5 минут или просто открыть терминал и запускать его, когда вы видите низкую производительность. Да, мне нужно добавить память на машину ...


Форматирование кажется проблемой, не знаю, как это исправить
Warpig

1
Используйте ссылку редактирования под вашим постом. Над текстовой областью есть панель инструментов форматирования и оранжевый вопросительный знак, указывающий на справку по форматированию Markdown .
Дэвид Фёрстер

Пожалуйста, посмотрите на мой недавний комментарий по этому вопросу . Я убежден, что идея освободить основную память путем очистки и сброса кэшей ошибочна, и я знаю, что я не одинок в этом заключении.
Дэвид Фёрстер,

Большое спасибо, Дэвид ... Я полностью согласен с тем, что очистка / удаление кэша ошибочно ... Но что-то зависает и заставляет машину зависать / зависать ... Просто сбит с толку относительно того, что это такое, думая, что это проблема с Firefox. ..
Warpig

3

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

memstat -w -p pid хорошая команда для использования.


1
ссылка не работает, я думаю, что это хорошо
vladkras

1

У меня была похожая проблема, но с очень странным решением.

По какой-то неизвестной причине у меня был установлен и работает почтовый сервер на ноутбуке. Я не знаю, почему он у меня был ... Однако я отключил его обслуживание, и оказалось, что это программное обеспечение на моем ноутбуке подверглось атаке ddos. После этого все было нормально.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.