Come posso trovare una perdita di memoria di un processo in esecuzione?


19

C'è un modo, posso trovare la perdita di memoria di un processo in esecuzione? Posso usare Valgrind per trovare perdite di memoria prima dell'inizio di un processo. Posso usare GDB per collegarlo a un processo in esecuzione. Come è possibile eseguire il debug di una perdita di memoria di un processo in esecuzione?


Valgrind è molto utile, lo definirei persino intuitivo.
user400344,

Risposte:


13

Ecco i passaggi per garantire quasi chi perde la memoria:

  1. Scopri il PID del processo che causa la perdita di memoria.

    ps -aux
  2. catturare /proc/PID/smapse salvare in alcuni file come BeforeMemInc.txt.

  3. attendere che la memoria venga aumentata.
  4. catturare di nuovo /proc/PID/smapse salvarlo haafterMemInc.txt
  5. trova la differenza tra primo smapse secondo smaps, ad es. con

    diff -u beforeMemInc.txt afterMemInc.txt

  6. annotare l'intervallo di indirizzi in cui è stata aumentata la memoria, ad esempio:

       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. utilizzare GDB per scaricare la memoria durante il processo in esecuzione o ottenere il coredump utilizzando gcore -o process

  8. Ho usato gdb sul processo in esecuzione per scaricare la memoria su alcuni file.

    gdb -p PID
    dump memory ./dump_outputfile.dump 0x2b3289290000 0x2b3289343000
  9. ora usa il stringscomando o hexdump -Cper stampare il filedump_outputfile.dump

    strings outputfile.dump
  10. Si ottiene un modulo leggibile in cui è possibile individuare tali stringhe nel codice sorgente.

  11. Analizza la tua fonte per trovare la perdita.


12

Penso che memleax sia esattamente quello che vuoi.

Esegue il debug della perdita di memoria di un processo in esecuzione collegandolo, senza ricompilare il programma o riavviare il processo di destinazione. È molto conveniente e adatto all'ambiente di produzione.

Funziona su GNU / Linux e FreeBSD.

NOTA: sono l'autore, ogni suggerimento è il benvenuto

== EDIT ==

Scrivo un altro strumento libleak , che aggancia le funzioni di memoria di LD_PRELOAD.

Non è inoltre necessario modificare il programma di destinazione. Sebbene sia necessario riavviare l'avanzamento con LD_PRELOAD, è possibile abilitare / disabilitare il rilevamento durante l'esecuzione.

C'è un impatto molto minore sulle prestazioni poiché nessuna trappola del segnale.

Rispetto a strumenti simili (come mtrace), stampa l'intero stack di chiamate in un punto di perdita di memoria sospetto.


1
Garantisco memleax come uno strumento molto utile per monitorare eventuali perdite evidenti. I riepiloghi dei risultati sono sorprendentemente efficaci . Quasi come se li scrivessi se avessi la potenza di elaborazione per farlo manualmente. Grazie per questo
vedi il

6

Su Linux, potresti abilitare mtrace nel tuo programma, ma si tratta di una modifica del codice.

Su OpenBSD, puoi provare le statistiche malloc .

Anche il correttore di perdite di Google potrebbe valere la pena di essere visto, e diversamente da mtrace potresti essere in grado di utilizzare LD_PRELOADper evitare la ricompilazione.


0

Penso che senza fornire supporto per il monitoraggio dell'allocazione dopo l'avvio del programma direttamente nel codice sorgente, sei sfortunato. Ecco due motivi a cui posso pensare:

  • I controlli heap vengono inizializzati all'avvio del programma. Alcuni offrono la possibilità di modificare i tempi esatti, ma le variabili d'ambiente che li avviano devono essere impostate all'avvio del programma. Questo perché guardano per assicurarsi che ogni allocazione abbia una deallocazione corrispondente e ne mancherebbero altrimenti.
  • Il controllo dell'heap in genere richiede privilegi o hook elevati, che devono essere forniti dal sistema operativo. Se tali hook non sono forniti al momento dell'avvio del programma, i controlli heap non possono sfruttarli. Non credo che i sistemi operativi forniscano questi privilegi dopo l'avvio del programma in questione.

Se, tuttavia, il programma è in esecuzione all'interno di una macchina virtuale, tale ambiente potrebbe fornire supporto per il monitoraggio delle allocazioni. So che Java ha diversi strumenti di monitoraggio dell'allocazione e della garbage collection (come visualVM ) che si collegano a programmi in esecuzione o VM.


0

Purify di IBM è probabilmente lo strumento più antico e sofisticato di tutti. Contrassegna il numero di riga nel codice che causa la perdita di memoria.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.