Как обнаружить утечку памяти?
Кажется, у меня большая утечка памяти в моей текущей системе Ubuntu
После сообщения о странных ошибках памяти Eclipse ( https://Ask-ubuntu.ru/questions/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
6 ответов
Memprof - это инструмент для профилирования использования памяти и обнаружения утечек памяти. Он может генерировать профиль, сколько памяти было выделено каждой функцией в вашей программе. Кроме того, он может сканировать память и находить блоки, которые вы выделили, но на которые больше нет ссылок.
Memprof работает путем предварительной загрузки библиотеки, чтобы переопределить функции выделения памяти библиотеки C, и не требует перекомпиляции вашей программы.
Источник: Руководство по Ubuntu
Вот почти гарантированные шаги, чтобы найти, кто утечка памяти:
Узнайте PID процесса, который вызывает утечку памяти.
ps -aux
захватить
/proc/PID/smaps
и сохранить в какой-то файл, какBeforeMemInc.txt
,- подождите, пока память не увеличится.
- захватить снова
/proc/PID/smaps
и сохранить это имеетafterMemInc.txt
найти разницу между первым
smaps
и 2-йsmaps
например, сdiff -u beforeMemInc.txt afterMemInc.txt
запишите диапазон адресов, в котором увеличилась память, например:
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
используйте GDB для выгрузки памяти на работающий процесс или получите coredump, используя
gcore -o process
Я использовал gdb при запуске процесса для выгрузки памяти в какой-то файл.
gdb -p PID dump memory ./dump_outputfile.dump 0x2b3289290000 0x2b3289343000
сейчас используй
strings
команда илиhexdump -C
распечататьdump_outputfile.dump
strings outputfile.dump
Вы получаете читаемую форму, где вы можете найти эти строки в вашем исходном коде.
Проанализируйте свой источник, чтобы найти утечку.
Трюк 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
чтобы получить процессы с наибольшим использованием памяти, в противном случае список процессов сортируется по возрастанию численных и дает процессам с наименьшим использованием памяти.
memstat также является хорошим инструментом, который покажет объем памяти, используемый каждым блоком, а также объем памяти, используемый загруженными библиотеками. Не лучший инструмент, но его стоит использовать для сбора деталей и статистики.
memstat -w -p pid
хорошая команда для использования.
У меня есть старая машина, которую я использую, которая постоянно выдает сообщения об утечке памяти:
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 минут или просто открыть терминал и запускать его, когда вы видите низкую производительность. Да, мне нужно добавить память на машину...
У меня была похожая проблема, но с очень странным решением.
По какой-то неизвестной причине у меня был установлен и работает почтовый сервер на ноутбуке. Я не знаю, почему он у меня был... Однако я отключил его обслуживание, и оказалось, что это программное обеспечение на моем ноутбуке подверглось атаке ddos. После этого все было нормально.