Як виявити витік пам'яті?


16

У мене, здається, є більший витік пам'яті в моїй теперішній системі ubuntu

Після повідомлення про дивні помилки пам'яті Eclipse ( /ubuntu/148998/eclipse-constant-different-out-of-memory-errors ) я сьогодні почав отримувати повідомлення про помилки "недостатньо пам'яті" у своїй консолі - поки виконувати прості завдання, такі як введення sudo -s- або навіть -free -m

Набравши 'free -m' неодноразово показав мені, як моя оперативна пам’ять швидко зростає з 700M до 900M, зростаючи до розміру 2000M за кілька секунд (після звільнення пам'яті за допомогою 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. Що я зробив неправильно?
Devy

Цей метод працював для мене до кроку 9. Витік у моєму випадку не містив жодних читабельних чи впізнаваних даних. Як я можу отримати назви символів даних, які просочилися?
Крейг

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
Скористайтеся посиланням для редагування під публікацією. Над полем тексту, що посилається на довідку щодо форматування відмітки, є панель інструментів форматування та помаранчевий знак питання .
Девід Фоерстер

Погляньте, будь ласка, на мій останній коментар до цього питання . Я переконаний, що ідея звільнити основну пам’ять шляхом промивання та скидання кешів помилкова, і я знаю, що я не один з цим висновком.
Девід Фоерстер

Велике спасибі, Девіде ... Я повністю погоджуюся з тим, що кеш-пам'ять промивається / випадає помилково ... Але щось зависає і змушує машину зависати / замикатися ... Просто дивуєшся, що це таке, думаючи, що це проблема Firefox. ..
Warpig

3

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

memstat -w -p pid це хороша команда для використання.


1
посилання порушено, я думаю, що це добре
vladkras

1

У мене була подібна проблема, але з дуже дивним рішенням.

З якихось невідомих причин у мене на поштовому сервері було налаштовано поштовий сервер і я не знаю, чому я його мав ... Однак я вимкнув його службу і виявилося, що це програмне забезпечення на моєму ноутбуці було під атакою ddos. Після цього все було нормально.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.