Jak wykryć wyciek pamięci?

16

Wydaje mi się, że mam większy wyciek pamięci w moim obecnym systemie Ubuntu

Po zgłoszeniu dziwnych błędów pamięci Eclipse ( /ubuntu/148998/eclipse-constant-different-out-of-memory-errors ) zacząłem dzisiaj otrzymywać komunikaty o błędach „Za mało pamięci” w mojej konsoli - podczas gdy wykonując proste zadania, takie jak wpisywanie sudo -s- a nawet -free -m

Wpisywanie „free-m” wielokrotnie pokazało mi, jak moja pamięć RAM szybko rośnie z 700M do 900M, a po kilku sekundach rośnie do wielkości 2000M (po zwolnieniu pamięci za pomocą echo 3 > /proc/sys/vm/drop_caches)

Zaćmienie nie jest przyczyną, całkowicie zabiłem proces, a baran wciąż się wznosił. Czy jest jakiś sposób na wykrycie, skąd pochodzi wyciek? Nie mogę nawet zaktualizować mojego systemu, ponieważ apt-get updatekończy się niepowodzeniem (prawdopodobnie dlatego, że brakuje pamięci)

Za pomocą Ubuntu 11.10

Katai
źródło
Jestem BARDZO szczęśliwy, że nie jestem szalony. Miałem ten sam problem od czasu aktualizacji do 13.10, ale pamiętam, że miałem to z 11.10. Pytanie brzmi: czy używasz CrashPlan? Wydaje mi się, że zawęziłem to do tego, po prostu nie wiem, jak to naprawić. Próbowałem ulepszenia pamięci, ale to nie działa. Mam nadzieję, że dostarczy ci pewnych wskazówek
pół-początkujący
Nie ma sensu zmuszać jądra do zrzucania pamięci podręcznych. Zostaną zarumienione, a ich przestrzeń zregenerowana, gdy tylko zajdzie potrzeba większej pamięci fizycznej. Wymuszone ich płukanie najprawdopodobniej nawet szkodzi ogólnej wydajności, ponieważ niebuforowane obiekty trzeba odzyskiwać z dużo wolniejszej pamięci dodatkowej. Wolna pamięć główna nie jest dobrą rzeczą. Jest to oznaka złego zarządzania pamięcią podręczną lub bardzo niewielkiego zużycia.
David Foerster

Odpowiedzi:

9

memprof to narzędzie do profilowania użycia pamięci i wykrywania wycieków pamięci. Może wygenerować profil, ile pamięci zostało przydzielone przez każdą funkcję w twoim programie. Ponadto może skanować pamięć i znajdować przydzielone bloki, ale nie są już nigdzie odniesienia.

memprof działa poprzez wstępne ładowanie biblioteki w celu zastąpienia funkcji alokacji pamięci biblioteki C i nie wymaga ponownej kompilacji programu.

memprof

Źródło: Podręcznik Ubuntu

Mitch
źródło
11

Po pierwsze, upewnij się, że masz dostępny folder tymczasowy z wystarczającą ilością wolnego miejsca. Następujące polecenia tworzą zrzuty, które mogą mieć rozmiar kilku GB.

Możesz utworzyć nowy folder tmp za pomocą następującego polecenia. Możesz przejść /tmpna inny system plików z wystarczającą ilością miejsca

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

Kroki, aby znaleźć wyciek pamięci

  1. Znajdź PID procesu powodującego wyciek pamięci (możesz również użyć np. htopJeśli jest dostępny) i zapisz go w zmiennej o nazwiepid

    ps -aux
    
  2. Biorąc pod uwagę, że PID jest dostępny w zmiennej pid, możesz przechwycić zużycie pamięci za pomocą /proc/$pid/smapsi zapisać w niektórych plikach takich jak beforeMemInc.txt.

    cat /proc/$pid/smaps > $TMPDIR/beforeMemInc.txt
    
  3. Zaczekaj, aż zużycie pamięci wzrośnie.
  4. Zrób /proc/$pid/smapsponownie i zapisz jakoafterMemInc.txt

    cat /proc/$pid/smaps > $TMPDIR/afterMemInc.txt
    
  5. Znajdź różnicę między pierwszym smapsa drugim smaps, np. Za pomocą

    diff -u $TMPDIR/beforeMemInc.txt $TMPDIR/afterMemInc.txt
    
  6. Zanotuj zakres adresów, w których wzrosła pamięć, na przykład:

       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. Użyj GDB, aby zrzucić pamięć przy uruchomionym procesie lub uzyskać zrzut rdzeniowy za pomocą

    gcore -o $TMPDIR/process $PID
    
  8. Użyłem gdb w uruchomionym procesie, aby zrzucić pamięć do jakiegoś pliku.

    cd $TMPDIR
    gdb -p $pid
    dump memory memory.dump 0x2b3289290000 0x2b3289343000
    
  9. Teraz użyj stringspolecenia lub, hexdump -Caby wydrukowaćmemory.dump

    strings memory.dump
    

    Z tego otrzymujesz czytelne informacje, które pomagają zlokalizować te ciągi w kodzie źródłowym.

  10. Przeanalizuj swoje źródło, aby znaleźć wyciek.
Jagannath Pattar
źródło
Jestem w kontenerze Docker i pojawia się błąd odmowy uprawnień podczas uruchamiania cat /proc/2882/smaps > /tmp/before.txtw kroku 2. Co zrobiłem źle?
Devy,
Ta metoda działała dla mnie aż do kroku 9. Wyciek w moim przypadku nie zawierał żadnych czytelnych ani rozpoznawalnych danych. Jak uzyskać nazwy symboli wyciekających danych?
Craig
8

Sztuczka drop_cache nie zwolni pamięci, zresetuje pamięć podręczną. Używa polecenia ps, jeśli chcesz określić, które procesy zużywają więcej pamięci.

Na przykład, aby monitorować listę 15 najlepszych użytkowników pamięci rezydentnej.

$ 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

Możesz również sprawdzić rezerwację pamięci współdzielonej, ale będziesz wiedział tylko, kto jest właścicielem segmentów.

Alokacja 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

zwróć uwagę, że zarezerwowane alokacje są znacznie wyższe niż rzeczywiste przydzielone strony (df „używane”)

Przydziały systemu 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         

Edycja : Musisz przejść, --sort -rssaby psuzyskać procesy o największym zużyciu pamięci, w przeciwnym razie lista procesów zostanie posortowana według wartości liczbowej i zapewni procesy o najmniejszym zużyciu pamięci.

Emmanuel
źródło
5

Mam starszą używaną maszynę, która ciągle wyrzuca komunikaty o wycieku pamięci:

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

Mój skrypt:

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

Nazwałem to 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

Widać, że spadłem do 374 MB, uruchomiłem sync; sudo echo 3 > /proc/sys/vm/drop_cachesi odzyskałem 417 MB. Można crongo uruchamiać co 5 minut lub po prostu mieć otwarty terminal i uruchamiać go, gdy widać niską wydajność. Tak, muszę dodać pamięć do maszyny ...

Warpig
źródło
Formatowanie wydaje się być problemem, nie jestem pewien, jak to naprawić
Warpig
1
Użyj linku edycyjnego pod postem. Nad polem tekstowym znajduje się pasek narzędzi do formatowania i pomarańczowy znak zapytania prowadzący do pomocy w formatowaniu Markdown .
David Foerster
Proszę spojrzeć na mój ostatni komentarz do pytania . Jestem przekonany, że pomysł na zwolnienie pamięci głównej przez opróżnianie pamięci podręcznej jest mylny i wiem, że nie jestem sam z tym wnioskiem.
David Foerster
Wielkie dzięki, David ... Całkowicie zgadzam się, że opróżnianie / upuszczanie pamięci podręcznej jest mylne ... Ale coś się rozłącza i powoduje zawieszanie się / blokowanie urządzenia ... Po prostu zdziwiłem się, co to jest, myśląc, że to problem z firefoxem. ..
Warpig,
3

memstat jest również dobrym narzędziem, które pokazuje ilość pamięci używanej przez każdy blok, a także ilość pamięci używanej przez załadowane biblioteki. Nie jest to najlepsze narzędzie, ale warto je wykorzystać do gromadzenia szczegółów i statystyk.

memstat -w -p pid to dobre polecenie do użycia.

Szef kuchni faraon
źródło
1
link jest zepsuty, myślę, że ten jest dobry
vladkras 13.10.16
1

Miałem podobny problem, ale z bardzo dziwnym rozwiązaniem.

Z jakiegoś nieznanego powodu miałem serwer poczty na konfiguracji i działającym laptopie. Nie wiem, dlaczego go miałem ... Jednak zamknąłem jego usługę i okazało się, że to oprogramowanie na moim laptopie było pod atakiem DDOS. Potem wszystko było normalne.

Mario Kamenjak
źródło