Come misurare l'utilizzo effettivo della memoria di un'applicazione o di un processo?


712

Questa domanda è trattata qui in dettaglio.

Come si misura l'utilizzo della memoria di un'applicazione o processo in Linux?

Dall'articolo del blog Comprensione dell'utilizzo della memoria su Linux , psnon è uno strumento preciso da utilizzare per questo scopo.

Perché psè "sbagliato"

A seconda di come lo si osserva, psnon viene riportato l'utilizzo della memoria reale dei processi. Quello che sta realmente facendo è mostrare quanta memoria reale occuperebbe ogni processo se fosse l'unico processo in esecuzione . Naturalmente, una tipica macchina Linux ha diverse decine di processi in esecuzione in un dato momento, il che significa che i numeri VSZ e RSS riportati da pssono quasi sicuramente sbagliati .


6
Al giorno d'oggi questa domanda probabilmente appartiene a serverfault.com, anche se mi sta dicendo che è "troppo vecchio per migrare". In realtà non voglio chiuderlo però ...
thomasrutter il

Fare riferimento a questa domanda. stackoverflow.com/questions/669438/…
Bloodmoon,

2
In realtà psnon mostra nemmeno questo: mostra i numeri di memoria virtuale e residente, dove virtuale è la massima quantità di memoria che il processo potrebbe teoricamente usarlo se fosse l'unico processo (mai così), utilizzato ogni singola pagina allocata (non succede mai) e non ha mappato o non mappato alcuna pagina (improbabile). Mentre residente mostra quanta memoria virtuale è mappata al fisico in questo momento. In genere, virt > usage > restuttavia, su un sistema a 64 bit virt ~= res*10è una gamma molto ampia.
Dima Tisnek,

5
L'estratto dell'articolo collegato è una totale assurdità. L'RSS è la memoria fisica effettivamente utilizzata e il VSZ può o meno tradursi in uso della memoria fisica anche se il processo era l'unico in esecuzione.
David Schwartz,

Risposte:


356

Con pso strumenti simili otterrai solo la quantità di pagine di memoria allocate da quel processo. Questo numero è corretto, ma:

  • non riflette la quantità effettiva di memoria utilizzata dall'applicazione, ma solo la quantità di memoria riservata ad essa

  • può essere fuorviante se le pagine sono condivise, ad esempio da più thread o utilizzando librerie collegate dinamicamente

Se vuoi davvero sapere quale quantità di memoria utilizza effettivamente l'applicazione, devi eseguirla all'interno di un profiler. Ad esempio, valgrindpuò fornire informazioni sulla quantità di memoria utilizzata e, cosa ancora più importante, su possibili perdite di memoria nel programma. Lo strumento profiler heap di valgrind si chiama 'massiccio':

Massif è un profilatore di heap. Esegue una profilazione dettagliata dell'heap eseguendo regolarmente istantanee dell'heap di un programma. Produce un grafico che mostra l'utilizzo dell'heap nel tempo, incluse informazioni su quali parti del programma sono responsabili della maggior parte delle allocazioni di memoria. Il grafico è integrato da un file di testo o HTML che include ulteriori informazioni per determinare dove viene allocata la maggior parte della memoria. Massif esegue i programmi circa 20 volte più lentamente del normale.

Come spiegato nella documentazione di valgrind , è necessario eseguire il programma tramite valgrind:

valgrind --tool=massif <executable> <arguments>

Massif scrive un dump di snapshot di utilizzo della memoria (ad es massif.out.12345.). Questi forniscono, (1) una sequenza temporale di utilizzo della memoria, (2) per ogni istantanea, un record di dove è stata allocata la memoria del programma. Un ottimo strumento grafico per analizzare questi file è il visualizzatore di massiccio . Ma ho scoperto che ms_printun semplice strumento basato su testo fornito con valgrind è già di grande aiuto.

Per trovare perdite di memoria, utilizzare lo memcheckstrumento (predefinito) di valgrind.


44
Per interpretare i risultati generati da valgrind, posso raccomandare alleyoop. Non è troppo elegante e ti dice semplicemente cosa devi sapere per individuare le fonti di perdite. Un bel paio di utilità.
Dan,

6
L'articolo (a) è corretto. Esiste una differenza tra le pagine utilizzate e la memoria effettivamente allocata dall'applicazione tramite chiamate a malloc (), new, ecc. L'utilizzo residente mostra solo la quantità di memoria paginata residente nella RAM.
jcoffland,

63
Questo non dice davvero come ottenere l'utilizzo della memoria usando valgrind?
Matt Joiner,

11
lo strumento valgrind predefinito, memcheck, è utile per rilevare perdite di memoria, ma non è proprio un profiler di memoria. Per questo, vuoi valgrind --tool = massiccio.
Todd ha liberato il

3
@DavidSchwartz Non vedo come la tua affermazione sia in contraddizione con la mia. Ho la sensazione che tu sia troppo preoccupato per il tuo punto di essere "sbagliato" piuttosto che leggere ciò che sto dicendo. Il mio punto qui è che l'RSS è una misura impropria per l'utilizzo della memoria reale dell'applicazione, e stai facendo lo stesso punto nelle ultime due frasi. Davvero, quale pensavi fosse la ragione per cui ho sollevato la contrazione RSS in primo luogo? In modo che me lo spieghi per dimostrarmi "sbagliato" con la cosa esatta a cui mi riferisco? Il tuo atteggiamento nei miei confronti è noioso.
ypnos,

280

Prova il comando pmap :

sudo pmap -x <process pid>

45
funziona con sudo o non dà alcun errore e non mostra memoria consumata.
Matt,

22
Non esiste su OSX (per chiunque venga qui da Google)
jcollum

3
Questa è una risposta completa alla domanda! ps. Nella mia shell, pmap può leggere il processo senza sudo.
MasterControlProgram

7
Per quanto riguarda OS X (apparentemente non la preoccupazione del PO), puoi vedere alcuni dati simili usando vmmap (1)
jrg

nota: dà una risposta completamente diversa dagnome-system-monitor
ribamar

190

Difficile dirlo con certezza, ma qui ci sono due cose "vicine" che possono aiutare.

$ ps aux 

ti darà Virtual Size (VSZ)

Puoi anche ottenere statistiche dettagliate dal file system / proc andando su /proc/$pid/status

Il più importante è VmSize, che dovrebbe essere vicino a ciò che ps auxdà.

/ proc / 19420 $ stato cat
Nome: firefox
Stato: S (dormendo)
Tgid: 19420
Pid: 19420
PPid: 1
TracerPid: 0
Uid: 1000 1000 1000 1000
Gid: 1000 1000 1000 1000
Dimensione FDS: 256
Gruppi: 4 6 20 24 25 29 30 44 46 107 109 115 124 1000 
VmPeak: 222956 kB
Dimensione Vm: 212520 kB
VmLck: 0 kB
VmHWM: 127912 kB
VmRSS: 118768 kB
VmData: 170180 kB
VmStk: 228 kB
VmExe: 28 kB
VmLib: 35424 kB
VmPTE: 184 kB
Discussioni: 8
SigQ: 0/16382
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000020001000
SigCgt: 000000018000442f
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
Cpus_allowed: 03
Mems_allowed: 1
voluntary_ctxt_switches: 63422
nonvoluntary_ctxt_switches: 7171


21
Mi sto perdendo qualcosa? La domanda si chiedeva come misurare meglio l'utilizzo della memoria da parte di un processo, dato che VSZ e RSS riportati in ps sono fuorvianti. La tua risposta spiega come cercare la VSZ, lo stesso valore che è stato menzionato come fuorviante.
thomasrutter,

16
@thomasrutter Sì, ti manca la domanda originale (rev 1), è stata modificata più volte ed è piuttosto vecchia (2008). La domanda originale ha appena chiesto come misurare l'utilizzo della memoria di un processo. Sentiti libero di modificare domande e risposte, tuttavia, se le cose sono obsolete. :)
DustinB,

1
nota: dà una risposta completamente diversa dagnome-system-monitor
ribamar

131

Nelle recenti versioni di Linux, utilizzare il sottosistema smaps . Ad esempio, per un processo con un PID di 1234:

cat /proc/1234/smaps

Ti dirà esattamente quanta memoria sta usando in quel momento. Ancora più importante, dividerà la memoria in privata e condivisa, quindi puoi dire quanta memoria sta usando la tua istanza del programma, senza includere la memoria condivisa tra più istanze del programma.


immagino pmapsia un'interfaccia più semplice.
ribamar,

126

Non esiste un modo semplice per calcolare questo. Ma alcune persone hanno cercato di ottenere delle buone risposte:


nice produce un elenco pulito di memoria e processo
Rubytastic,

Molto bello, con un raggruppamento abbastanza intelligente.
Rohmer,

Sì, davvero carino. Trovo ps_meme smemmolto utile per le misure dell'utente finale, mentre ad es. pmapL 'output molto dettagliato è orientato verso gli sviluppatori ... consente di recuperare l' utilizzo della memoria di Firefox per ogni font, componenti aggiuntivi, librerie per esempio. Grazie a tutti exp. @Bash, @thomasruther.
tuk0z,

questo è finora l'unico a corrispondere all'output dignome-system-monitor
ribamar

110

Usa smem , che è un'alternativa a ps che calcola USS e PSS per processo. Quello che vuoi è probabilmente il PSS.

  • USS - Dimensioni univoche del set. Questa è la quantità di memoria non condivisa unica per quel processo (pensala come U per memoria unica ). Non include la memoria condivisa. Così questo testamento sotto -report la quantità di memoria a usi di processo, ma è utile quando si desidera ignorare memoria condivisa.

  • PSS - Dimensioni proporzionali impostate. Questo è quello che vuoi. Aggiunge la memoria unica (USS), insieme a una parte della sua memoria condivisa divisa per il numero di processi che condividono quella memoria. Quindi ti darà una rappresentazione accurata della quantità di memoria fisica effettiva utilizzata per processo - con la memoria condivisa rappresentata realmente come condivisa. Pensa alla P come memoria fisica .

Come questo si confronta con RSS come riportato da ps e altre utilità:

  • RSS - Dimensione set residenti. Questa è la quantità di memoria condivisa più memoria non condivisa utilizzata da ciascun processo. Se la memoria dei processi azione, questo sarà sopra -report la quantità di memoria effettivamente utilizzato, perché la stessa memoria condivisa sarà conteggiato più di una volta - che appare di nuovo in ogni altro processo che condivide la stessa memoria. Quindi è abbastanza inaffidabile, specialmente quando i processi ad alta memoria hanno molte forcelle, cosa comune in un server, con processi come Apache o PHP (fastcgi / FPM).

Nota: smem può anche (facoltativamente) generare grafici come grafici a torta e simili. IMO non ti serve nulla di tutto ciò. Se vuoi semplicemente usarlo dalla riga di comando come potresti usare ps -A v, non è necessario installare la dipendenza consigliata da python-matplotlib.


2
Un punto critico sull'RSS è che la maggior parte delle applicazioni oggigiorno condivide molte pagine di codice. Ogni libreria condivisa (ad es. Libc e libstdc ++) verrà conteggiata per ogni processo che la utilizza. E se ci sono più istanze di un processo in esecuzione, tutto quel codice verrà conteggiato due volte.
David C.

1
Proprio per questo motivo l'RSS segnala eccessivamente in termini di memoria fisica effettiva per processo.
thomasrutter,

3
smem è ciò di cui avevo bisogno. Eseguendolo con -t ogni volta che avvio una nuova istanza del processo, posso vedere la memoria consumata da ciascuna istanza. Per chrome: smem -t -P '/ opt / google / chrome'
xtian

Sto facendo fatica a trovare la documentazione per smem .. per impostazione predefinita viene generato in byte, kilobyte o megabyte ??
ZN13

4
TL; DR: USS = quantità di memoria fisica che verrà liberata se il processo viene interrotto, PSS = quantità di memoria fisica di cui questo processo ha bisogno dal sistema se nessun processo esistente verrà ucciso, RSS = quantità di memoria fisica accessibile da questo processo (ma non sempre l'accesso esclusivo).
Mikko Rantalainen,

95
ps -eo size,pid,user,command --sort -size | \
    awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }' |\
    cut -d "" -f2 | cut -d "-" -f1

Usa questo come root e puoi ottenere un chiaro output per l'utilizzo della memoria da ogni processo.

ESEMPIO DI USCITA:

     0.00 Mb COMMAND 
  1288.57 Mb /usr/lib/firefox
   821.68 Mb /usr/lib/chromium/chromium 
   762.82 Mb /usr/lib/chromium/chromium 
   588.36 Mb /usr/sbin/mysqld 
   547.55 Mb /usr/lib/chromium/chromium 
   523.92 Mb /usr/lib/tracker/tracker
   476.59 Mb /usr/lib/chromium/chromium 
   446.41 Mb /usr/bin/gnome
   421.62 Mb /usr/sbin/libvirtd 
   405.11 Mb /usr/lib/chromium/chromium 
   302.60 Mb /usr/lib/chromium/chromium 
   291.46 Mb /usr/lib/chromium/chromium 
   284.56 Mb /usr/lib/chromium/chromium 
   238.93 Mb /usr/lib/tracker/tracker
   223.21 Mb /usr/lib/chromium/chromium 
   197.99 Mb /usr/lib/chromium/chromium 
   194.07 Mb conky 
   191.92 Mb /usr/lib/chromium/chromium 
   190.72 Mb /usr/bin/mongod 
   169.06 Mb /usr/lib/chromium/chromium 
   155.11 Mb /usr/bin/gnome
   136.02 Mb /usr/lib/chromium/chromium 
   125.98 Mb /usr/lib/chromium/chromium 
   103.98 Mb /usr/lib/chromium/chromium 
    93.22 Mb /usr/lib/tracker/tracker
    89.21 Mb /usr/lib/gnome
    80.61 Mb /usr/bin/gnome
    77.73 Mb /usr/lib/evolution/evolution
    76.09 Mb /usr/lib/evolution/evolution
    72.21 Mb /usr/lib/gnome
    69.40 Mb /usr/lib/evolution/evolution
    68.84 Mb nautilus
    68.08 Mb zeitgeist
    60.97 Mb /usr/lib/tracker/tracker
    59.65 Mb /usr/lib/evolution/evolution
    57.68 Mb apt
    55.23 Mb /usr/lib/gnome
    53.61 Mb /usr/lib/evolution/evolution
    53.07 Mb /usr/lib/gnome
    52.83 Mb /usr/lib/gnome
    51.02 Mb /usr/lib/udisks2/udisksd 
    50.77 Mb /usr/lib/evolution/evolution
    50.53 Mb /usr/lib/gnome
    50.45 Mb /usr/lib/gvfs/gvfs
    50.36 Mb /usr/lib/packagekit/packagekitd 
    50.14 Mb /usr/lib/gvfs/gvfs
    48.95 Mb /usr/bin/Xwayland :1024 
    46.21 Mb /usr/bin/gnome
    42.43 Mb /usr/bin/zeitgeist
    42.29 Mb /usr/lib/gnome
    41.97 Mb /usr/lib/gnome
    41.64 Mb /usr/lib/gvfs/gvfsd
    41.63 Mb /usr/lib/gvfs/gvfsd
    41.55 Mb /usr/lib/gvfs/gvfsd
    41.48 Mb /usr/lib/gvfs/gvfsd
    39.87 Mb /usr/bin/python /usr/bin/chrome
    37.45 Mb /usr/lib/xorg/Xorg vt2 
    36.62 Mb /usr/sbin/NetworkManager 
    35.63 Mb /usr/lib/caribou/caribou 
    34.79 Mb /usr/lib/tracker/tracker
    33.88 Mb /usr/sbin/ModemManager 
    33.77 Mb /usr/lib/gnome
    33.61 Mb /usr/lib/upower/upowerd 
    33.53 Mb /usr/sbin/gdm3 
    33.37 Mb /usr/lib/gvfs/gvfsd
    33.36 Mb /usr/lib/gvfs/gvfs
    33.23 Mb /usr/lib/gvfs/gvfs
    33.15 Mb /usr/lib/at
    33.15 Mb /usr/lib/at
    30.03 Mb /usr/lib/colord/colord 
    29.62 Mb /usr/lib/apt/methods/https 
    28.06 Mb /usr/lib/zeitgeist/zeitgeist
    27.29 Mb /usr/lib/policykit
    25.55 Mb /usr/lib/gvfs/gvfs
    25.55 Mb /usr/lib/gvfs/gvfs
    25.23 Mb /usr/lib/accountsservice/accounts
    25.18 Mb /usr/lib/gvfs/gvfsd 
    25.15 Mb /usr/lib/gvfs/gvfs
    25.15 Mb /usr/lib/gvfs/gvfs
    25.12 Mb /usr/lib/gvfs/gvfs
    25.10 Mb /usr/lib/gnome
    25.10 Mb /usr/lib/gnome
    25.07 Mb /usr/lib/gvfs/gvfsd 
    24.99 Mb /usr/lib/gvfs/gvfs
    23.26 Mb /usr/lib/chromium/chromium 
    22.09 Mb /usr/bin/pulseaudio 
    19.01 Mb /usr/bin/pulseaudio 
    18.62 Mb (sd
    18.46 Mb (sd
    18.30 Mb /sbin/init 
    18.17 Mb /usr/sbin/rsyslogd 
    17.50 Mb gdm
    17.42 Mb gdm
    17.09 Mb /usr/lib/dconf/dconf
    17.09 Mb /usr/lib/at
    17.06 Mb /usr/lib/gvfs/gvfsd
    16.98 Mb /usr/lib/at
    16.91 Mb /usr/lib/gdm3/gdm
    16.86 Mb /usr/lib/gvfs/gvfsd
    16.86 Mb /usr/lib/gdm3/gdm
    16.85 Mb /usr/lib/dconf/dconf
    16.85 Mb /usr/lib/dconf/dconf
    16.73 Mb /usr/lib/rtkit/rtkit
    16.69 Mb /lib/systemd/systemd
    13.13 Mb /usr/lib/chromium/chromium 
    13.13 Mb /usr/lib/chromium/chromium 
    10.92 Mb anydesk 
     8.54 Mb /sbin/lvmetad 
     7.43 Mb /usr/sbin/apache2 
     6.82 Mb /usr/sbin/apache2 
     6.77 Mb /usr/sbin/apache2 
     6.73 Mb /usr/sbin/apache2 
     6.66 Mb /usr/sbin/apache2 
     6.64 Mb /usr/sbin/apache2 
     6.63 Mb /usr/sbin/apache2 
     6.62 Mb /usr/sbin/apache2 
     6.51 Mb /usr/sbin/apache2 
     6.25 Mb /usr/sbin/apache2 
     6.22 Mb /usr/sbin/apache2 
     3.92 Mb bash 
     3.14 Mb bash 
     2.97 Mb bash 
     2.95 Mb bash 
     2.93 Mb bash 
     2.91 Mb bash 
     2.86 Mb bash 
     2.86 Mb bash 
     2.86 Mb bash 
     2.84 Mb bash 
     2.84 Mb bash 
     2.45 Mb /lib/systemd/systemd
     2.30 Mb (sd
     2.28 Mb /usr/bin/dbus
     1.84 Mb /usr/bin/dbus
     1.46 Mb ps 
     1.21 Mb openvpn hackthebox.ovpn 
     1.16 Mb /sbin/dhclient 
     1.16 Mb /sbin/dhclient 
     1.09 Mb /lib/systemd/systemd 
     0.98 Mb /sbin/mount.ntfs /dev/sda3 /media/n0bit4/Data 
     0.97 Mb /lib/systemd/systemd 
     0.96 Mb /lib/systemd/systemd 
     0.89 Mb /usr/sbin/smartd 
     0.77 Mb /usr/bin/dbus
     0.76 Mb su 
     0.76 Mb su 
     0.76 Mb su 
     0.76 Mb su 
     0.76 Mb su 
     0.76 Mb su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.74 Mb /usr/bin/dbus
     0.71 Mb /usr/lib/apt/methods/http 
     0.68 Mb /bin/bash /usr/bin/mysqld_safe 
     0.68 Mb /sbin/wpa_supplicant 
     0.66 Mb /usr/bin/dbus
     0.61 Mb /lib/systemd/systemd
     0.54 Mb /usr/bin/dbus
     0.46 Mb /usr/sbin/cron 
     0.45 Mb /usr/sbin/irqbalance 
     0.43 Mb logger 
     0.41 Mb awk { hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" } 
     0.40 Mb /usr/bin/ssh
     0.34 Mb /usr/lib/chromium/chrome
     0.32 Mb cut 
     0.32 Mb cut 
     0.00 Mb [kthreadd] 
     0.00 Mb [ksoftirqd/0] 
     0.00 Mb [kworker/0:0H] 
     0.00 Mb [rcu_sched] 
     0.00 Mb [rcu_bh] 
     0.00 Mb [migration/0] 
     0.00 Mb [lru
     0.00 Mb [watchdog/0] 
     0.00 Mb [cpuhp/0] 
     0.00 Mb [cpuhp/1] 
     0.00 Mb [watchdog/1] 
     0.00 Mb [migration/1] 
     0.00 Mb [ksoftirqd/1] 
     0.00 Mb [kworker/1:0H] 
     0.00 Mb [cpuhp/2] 
     0.00 Mb [watchdog/2] 
     0.00 Mb [migration/2] 
     0.00 Mb [ksoftirqd/2] 
     0.00 Mb [kworker/2:0H] 
     0.00 Mb [cpuhp/3] 
     0.00 Mb [watchdog/3] 
     0.00 Mb [migration/3] 
     0.00 Mb [ksoftirqd/3] 
     0.00 Mb [kworker/3:0H] 
     0.00 Mb [kdevtmpfs] 
     0.00 Mb [netns] 
     0.00 Mb [khungtaskd] 
     0.00 Mb [oom_reaper] 
     0.00 Mb [writeback] 
     0.00 Mb [kcompactd0] 
     0.00 Mb [ksmd] 
     0.00 Mb [khugepaged] 
     0.00 Mb [crypto] 
     0.00 Mb [kintegrityd] 
     0.00 Mb [bioset] 
     0.00 Mb [kblockd] 
     0.00 Mb [devfreq_wq] 
     0.00 Mb [watchdogd] 
     0.00 Mb [kswapd0] 
     0.00 Mb [vmstat] 
     0.00 Mb [kthrotld] 
     0.00 Mb [ipv6_addrconf] 
     0.00 Mb [acpi_thermal_pm] 
     0.00 Mb [ata_sff] 
     0.00 Mb [scsi_eh_0] 
     0.00 Mb [scsi_tmf_0] 
     0.00 Mb [scsi_eh_1] 
     0.00 Mb [scsi_tmf_1] 
     0.00 Mb [scsi_eh_2] 
     0.00 Mb [scsi_tmf_2] 
     0.00 Mb [scsi_eh_3] 
     0.00 Mb [scsi_tmf_3] 
     0.00 Mb [scsi_eh_4] 
     0.00 Mb [scsi_tmf_4] 
     0.00 Mb [scsi_eh_5] 
     0.00 Mb [scsi_tmf_5] 
     0.00 Mb [bioset] 
     0.00 Mb [kworker/1:1H] 
     0.00 Mb [kworker/3:1H] 
     0.00 Mb [kworker/0:1H] 
     0.00 Mb [kdmflush] 
     0.00 Mb [bioset] 
     0.00 Mb [kdmflush] 
     0.00 Mb [bioset] 
     0.00 Mb [jbd2/sda5
     0.00 Mb [ext4
     0.00 Mb [kworker/2:1H] 
     0.00 Mb [kauditd] 
     0.00 Mb [bioset] 
     0.00 Mb [drbd
     0.00 Mb [irq/27
     0.00 Mb [i915/signal:0] 
     0.00 Mb [i915/signal:1] 
     0.00 Mb [i915/signal:2] 
     0.00 Mb [ttm_swap] 
     0.00 Mb [cfg80211] 
     0.00 Mb [kworker/u17:0] 
     0.00 Mb [hci0] 
     0.00 Mb [hci0] 
     0.00 Mb [kworker/u17:1] 
     0.00 Mb [iprt
     0.00 Mb [iprt
     0.00 Mb [kworker/1:0] 
     0.00 Mb [kworker/3:0] 
     0.00 Mb [kworker/0:0] 
     0.00 Mb [kworker/2:0] 
     0.00 Mb [kworker/u16:0] 
     0.00 Mb [kworker/u16:2] 
     0.00 Mb [kworker/3:2] 
     0.00 Mb [kworker/2:1] 
     0.00 Mb [kworker/1:2] 
     0.00 Mb [kworker/0:2] 
     0.00 Mb [kworker/2:2] 
     0.00 Mb [kworker/0:1] 
     0.00 Mb [scsi_eh_6] 
     0.00 Mb [scsi_tmf_6] 
     0.00 Mb [usb
     0.00 Mb [bioset] 
     0.00 Mb [kworker/3:1] 
     0.00 Mb [kworker/u16:1] 

1
Un modo per filtrare l'elenco in modo da avere solo processi che usano più del 25% della memoria per 30 anni? Sto cercando di vedere i processi di fuga, come il browser Chrome quando si utilizza un debugger PHPEclipse.
Stephane,

quel filtro sarebbe fantastico
aleix il

1
Lo posterò appena posso.
Lokendra Singh Rawat,

2
Grande! Ma il loop dovrebbe iniziare da x=2anche output pid e user.
Boris Brodski,

70

Che dire time?

Non il Bash incorporato, timema quello con cui puoi trovare which time, per esempio/usr/bin/time

Ecco cosa copre, in modo semplice ls:

$ /usr/bin/time --verbose ls
(...)
Command being timed: "ls"
User time (seconds): 0.00
System time (seconds): 0.00
Percent of CPU this job got: 0%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 2372
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 1
Minor (reclaiming a frame) page faults: 121
Voluntary context switches: 2
Involuntary context switches: 9
Swaps: 0
File system inputs: 256
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0

Io sono anche. È il modo in cui uso per profilare le attività in powercron.eu :)
Moonchild,

5
brew install gnu-timequindi usalo gtimese sei su macOS.
Nobu,

4
Svantaggio: non otterrai i risultati fino a quando il processo non avrà completato la sua esecuzione. Non può essere utilizzato per il monitoraggio in tempo reale del processo in esecuzione.
Makesh

/ usr / bin / time -f '% M'
infomaniac

1
Puoi anche invocarlo usando \ time (con una barra rovesciata per evitare di usare il tempo interno della shell).
Raúl Salinas-Monteagudo,

39

Questo è un eccellente riassunto degli strumenti e dei problemi: collegamento archive.org

Lo citerò, in modo che più sviluppatori lo leggano.

Se si desidera analizzare l'utilizzo della memoria dell'intero sistema o analizzare in modo approfondito l'utilizzo della memoria di un'applicazione (non solo l'utilizzo dell'heap), utilizzare exmap . Per l'analisi dell'intero sistema, trovano i processi con il massimo utilizzo effettivo, prendono in pratica la maggior quantità di memoria, trovano processi con il più elevato utilizzo scrivibile, creano la maggior parte dei dati (e quindi possibilmente perdono o sono molto inefficaci nel loro utilizzo dei dati). Seleziona tale applicazione e analizzane i mapping nella seconda visualizzazione elenco. Vedi la sezione exmap per maggiori dettagli. Utilizza anche xrestop per verificare l'utilizzo elevato delle risorse X, soprattutto se il processo del server X richiede molta memoria. Vedi la sezione xrestop per i dettagli.

Se si desidera rilevare perdite, utilizzare valgrind o eventualmente kmtrace .

Se si desidera analizzare l'utilizzo dell'heap (malloc ecc.) Di un'applicazione, eseguirlo in memprof o con kmtrace , creare un profilo dell'applicazione e cercare nella struttura delle chiamate di funzione le allocazioni maggiori. Vedi le loro sezioni per maggiori dettagli.


28

Oltre alle soluzioni elencate nelle tue risposte, puoi usare il comando Linux "top"; Fornisce una visione dinamica in tempo reale del sistema in esecuzione, fornisce in percentuale l'utilizzo della CPU e della memoria per l'intero sistema e per ogni programma:

top

filtrare per pid del programma:

top -p <PID>

per filtrare in base al nome di un programma:

top | grep <PROCESS NAME>

"top" fornisce anche alcuni campi come:

VIRT - Immagine virtuale (kb): la quantità totale di memoria virtuale utilizzata dall'attività

RES - Dimensione residente (kb): la memoria fisica non scambiata utilizzata da un'attività; RES = CODICE + DATI.

DATA - Data + Stack size (kb): la quantità di memoria fisica dedicata a un codice diverso dal codice eseguibile, noto anche come dimensione del "set di dati residenti" o DRS.

SHR - Dimensione memoria condivisa (kb): la quantità di memoria condivisa utilizzata da un'attività. Riflette semplicemente la memoria che potrebbe essere potenzialmente condivisa con altri processi.

Riferimento qui .


20

Non esiste una sola risposta per questo perché non è possibile individuare con precisione la quantità di memoria utilizzata da un processo. La maggior parte dei processi su Linux utilizza librerie condivise. Ad esempio, supponiamo che tu voglia calcolare l'utilizzo della memoria per il processo 'ls'. Conti solo la memoria utilizzata dall'eseguibile 'ls' (se potessi isolarla)? Che ne dici di libc? O tutte queste altre librerie necessarie per eseguire 'ls'?

linux-gate.so.1 =>  (0x00ccb000)
librt.so.1 => /lib/librt.so.1 (0x06bc7000)
libacl.so.1 => /lib/libacl.so.1 (0x00230000)
libselinux.so.1 => /lib/libselinux.so.1 (0x00162000)
libc.so.6 => /lib/libc.so.6 (0x00b40000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00cb4000)
/lib/ld-linux.so.2 (0x00b1d000)
libattr.so.1 => /lib/libattr.so.1 (0x00229000)
libdl.so.2 => /lib/libdl.so.2 (0x00cae000)
libsepol.so.1 => /lib/libsepol.so.1 (0x0011a000)

Si potrebbe obiettare che sono condivisi da altri processi, ma 'ls' non può essere eseguito sul sistema senza che vengano caricati.

Inoltre, se è necessario conoscere la quantità di memoria necessaria a un processo per eseguire la pianificazione della capacità, è necessario calcolare la quantità utilizzata da ogni copia aggiuntiva del processo. Penso che / proc / PID / status possa darti abbastanza informazioni sull'uso della memoria in una sola volta. D'altra parte, valgrind ti darà un profilo migliore dell'utilizzo della memoria per tutta la durata del programma


Sto cercando di trovare quanta memoria sta assumendo un processo su una VM e voglio usarla per impostare il limite di memoria in kubernetes, sono d'accordo su questa risposta, quindi userò la memoria mostrata dapmap
Deepak Deore il

16

Se il tuo codice è in C o C ++ potresti essere in grado di utilizzare ciò getrusage()che ti restituisce varie statistiche sulla memoria e sull'utilizzo del tempo del tuo processo.

Tuttavia, non tutte le piattaforme lo supportano e restituiranno 0 valori per le opzioni di utilizzo della memoria.

Invece puoi guardare il file virtuale creato in /proc/[pid]/statm(dove [pid]viene sostituito dal tuo ID di processo. Puoi ottenerlo da getpid()).

Questo file apparirà come un file di testo con 7 numeri interi. Probabilmente sei più interessato al primo (tutto l'utilizzo della memoria) e al sesto (uso della memoria dati) in questo file.


Si noti che questo non è supportato su tutte le piattaforme.
CashCow,

Secondo la pagina man di Linux ( linux.die.net/man/2/getrusage ), getrusage fa parte delle specifiche SVr4, 4.3BSD e POSIX.1-2001 (notando che POSIX specifica solo i campi utime e stime.) I non mi aspetto che funzioni su piattaforme non UNIX (tranne, forse, tramite un ambiente come Cygwin che fornisce funzionalità UNIX per altre piattaforme).
David C.

@DavidC. l'OP chiede di Linux.
Alexis Wilke,

@CashCow, intendevi dire getpid(), perché non conosco una getprocessid()funzione in C / C ++ sotto Linux.
Alexis Wilke,

12

Valgrind può mostrare informazioni dettagliate ma rallenta in modo significativo l'applicazione di destinazione e, nella maggior parte dei casi, modifica il comportamento dell'app.
Exmap era qualcosa che non conoscevo ancora, ma sembra che tu abbia bisogno di un modulo del kernel per ottenere le informazioni, che può essere un ostacolo.

Suppongo che ciò che tutti vogliono sapere "utilizzo della memoria" WRT è il seguente ...
In Linux, la quantità di memoria fisica che un singolo processo potrebbe utilizzare può essere approssimativamente suddivisa nelle seguenti categorie.

  • Ma memoria mappata anonima

    • .p privato
      • .d dirty == malloc / mmapped heap e stack allocati e memoria scritta
      • .c clean == malloc / mmapped heap e memoria dello stack una volta allocati, scritti, quindi liberati, ma non ancora recuperati
    • .s condiviso
      • .d dirty == heap malloc / mmaped potrebbe essere copiato e condiviso tra i processi (modificato)
      • .c clean == heap malloc / mmaped potrebbe essere copiato e condiviso tra i processi (modificato)
  • Memoria mappata denominata Mn

    • .p privato
      • .d dirty == file mmapped memoria scritta privata
      • .c clean == programma mappato / testo della libreria mappato privatamente
    • .s condiviso
      • .d dirty == file mmapped memory scritto condiviso
      • .c clean == mappato testo della libreria condiviso mappato

L'utilità inclusa in Android chiamata showmap è abbastanza utile

virtual                    shared   shared   private  private
size     RSS      PSS      clean    dirty    clean    dirty    object
-------- -------- -------- -------- -------- -------- -------- ------------------------------
       4        0        0        0        0        0        0 0:00 0                  [vsyscall]
       4        4        0        4        0        0        0                         [vdso]
      88       28       28        0        0        4       24                         [stack]
      12       12       12        0        0        0       12 7909                    /lib/ld-2.11.1.so
      12        4        4        0        0        0        4 89529                   /usr/lib/locale/en_US.utf8/LC_IDENTIFICATION
      28        0        0        0        0        0        0 86661                   /usr/lib/gconv/gconv-modules.cache
       4        0        0        0        0        0        0 87660                   /usr/lib/locale/en_US.utf8/LC_MEASUREMENT
       4        0        0        0        0        0        0 89528                   /usr/lib/locale/en_US.utf8/LC_TELEPHONE
       4        0        0        0        0        0        0 89527                   /usr/lib/locale/en_US.utf8/LC_ADDRESS
       4        0        0        0        0        0        0 87717                   /usr/lib/locale/en_US.utf8/LC_NAME
       4        0        0        0        0        0        0 87873                   /usr/lib/locale/en_US.utf8/LC_PAPER
       4        0        0        0        0        0        0 13879                   /usr/lib/locale/en_US.utf8/LC_MESSAGES/SYS_LC_MESSAGES
       4        0        0        0        0        0        0 89526                   /usr/lib/locale/en_US.utf8/LC_MONETARY
       4        0        0        0        0        0        0 89525                   /usr/lib/locale/en_US.utf8/LC_TIME
       4        0        0        0        0        0        0 11378                   /usr/lib/locale/en_US.utf8/LC_NUMERIC
    1156        8        8        0        0        4        4 11372                   /usr/lib/locale/en_US.utf8/LC_COLLATE
     252        0        0        0        0        0        0 11321                   /usr/lib/locale/en_US.utf8/LC_CTYPE
     128       52        1       52        0        0        0 7909                    /lib/ld-2.11.1.so
    2316       32       11       24        0        0        8 7986                    /lib/libncurses.so.5.7
    2064        8        4        4        0        0        4 7947                    /lib/libdl-2.11.1.so
    3596      472       46      440        0        4       28 7933                    /lib/libc-2.11.1.so
    2084        4        0        4        0        0        0 7995                    /lib/libnss_compat-2.11.1.so
    2152        4        0        4        0        0        0 7993                    /lib/libnsl-2.11.1.so
    2092        0        0        0        0        0        0 8009                    /lib/libnss_nis-2.11.1.so
    2100        0        0        0        0        0        0 7999                    /lib/libnss_files-2.11.1.so
    3752     2736     2736        0        0      864     1872                         [heap]
      24       24       24        0        0        0       24 [anon]
     916      616      131      584        0        0       32                         /bin/bash
-------- -------- -------- -------- -------- -------- -------- ------------------------------
   22816     4004     3005     1116        0      876     2012 TOTAL

10

Altri tre metodi da provare:

  1. ps aux --sort pmem
    Ordina l'output per %MEM.
  2. ps aux | awk '{print $2, $4, $11}' | sort -k2r | head -n 15
    Si ordina usando i tubi.
  3. top -a
    Inizia l'ordinamento principale per %MEM

(Estratto da qui )


2
tope probabilmente gli altri non danno una rappresentazione accurata della memoria effettivamente utilizzata dal processo. Ad esempio, ho 64GiB di RAM e ho 10 postgresprocessi ciascuno con report 16GiB RES e 25% MEM. Ovviamente, non possono usare tutti il ​​25% ... Ognuno ha anche 15GiB SHR, e sembra che lo stiano condividendo.
sudo,

8
#!/bin/ksh
#
# Returns total memory used by process $1 in kb.
#
# See /proc/NNNN/smaps if you want to do something
# more interesting.
#

IFS=$'\n'

for line in $(</proc/$1/smaps)
do
   [[ $line =~ ^Size:\s+(\S+) ]] && ((kb += ${.sh.match[1]}))
done

print $kb

5
ksh è una shell standard. Potrebbe non essere installato di default su distribuzioni Linux per utenti desktop o per scopi minimalisti, ma è solo un comando di distanza in quasi tutti i sistemi operativi unix- / linux. (cioè su tutti i BSD, su tutti i veri UNIX, su RHEL, su SLES, su Debian, su Ubuntu, su OSX)
Florian Heigl,

Questo file è accessibile, per impostazione predefinita, solo all'utente root.
Dmitry Ginzburg,

Di seguito è appena riscritto sed | awke funziona sopra in Busybox v1.23.2: sed -n 's/^Size:\s\+\(\S\+\) .*/\1/p' /proc/$1/smaps | awk '{s+=$1} END {print s}'
Ján Sáreník

1
@Catskul - Lo standard POSIX specifica la sua shell standard come un sottoinsieme rigoroso della shell Korn, una versione migliorata della shell Bourne.
ceph3us,

8

Sto usando htop; è un ottimo programma console simile al Task Manager di Windows.


Ho usato htoped è migliore di top ma ti mostrerà comunque tutti i thread di diverse app senza raggrupparli rendendoli quasi inutili come top.
sorin,

1
$ htop -p $ (pgrep <nome processo> | xargs | tr '' ',')
AAAfarmclub

6

Se il processo non utilizza troppa memoria (o perché si prevede che ciò accada, o qualche altro comando ha fornito questa indicazione iniziale) e il processo può resistere all'arresto per un breve periodo di tempo, è possibile provare a usa il comando gcore.

gcore <pid>

Controlla le dimensioni del file core generato per avere una buona idea della quantità di memoria utilizzata da un determinato processo.

Questo non funzionerà troppo bene se il processo utilizza centinaia di meg, o concerti, poiché la generazione del core potrebbe richiedere alcuni secondi o minuti per essere creata a seconda delle prestazioni I / O. Durante la creazione del core il processo viene arrestato (o "congelato") per impedire modifiche alla memoria. Quindi sii attento.

Assicurarsi inoltre che il punto di montaggio in cui viene generato il core disponga di molto spazio su disco e che il sistema non reagisca negativamente al file core che viene creato in quella particolare directory.


6

Sto usando Arch Linux e c'è questo meraviglioso pacchetto chiamato ps_mem

ps_mem -p <pid>

Esempio di output

$ ps_mem -S -p $(pgrep firefox)

Private   +   Shared  =  RAM used   Swap used   Program

355.0 MiB +  38.7 MiB = 393.7 MiB    35.9 MiB   firefox
---------------------------------------------
                        393.7 MiB    35.9 MiB
=============================================

5

Sotto la riga di comando troverai la memoria totale usata dai vari processi in esecuzione sulla macchina Linux in MB

ps -eo size,pid,user,command --sort -size | awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }' | awk '{total=total + $1} END {print total}'

5

Un buon test dell'utilizzo più "reale" è aprire l'applicazione, quindi eseguire vmstat -se controllare la statistica "memoria attiva". Chiudi l'applicazione, attendi qualche secondo ed esegui di vmstat -snuovo. Tuttavia, molta memoria attiva liberata era evidentemente utilizzata dall'app.


3
Come sarebbe meglio di ps ?? Viene fornito con tutte le limitazioni di ps ed è ancora più impreciso ...
Lester Cheung,

Un tipico sistema Unix ha molti processi che iniziano e finiscono continuamente. Non è possibile prevedere la RAM libera.
Raúl Salinas-Monteagudo,

4

Ottieni valgrind. dagli il tuo programma da eseguire e ti dirà molto sull'utilizzo della memoria.

Ciò si applicherebbe solo nel caso di un programma che gira da tempo e si ferma. Non so se valgrind può mettere le mani su un processo già in esecuzione o non dovrebbe fermare processi come i demoni.


No, non è possibile "collegare" valgrind a un processo in esecuzione. Questo è di progettazione.
Dima Tisnek,

3

Modifica: funziona bene al 100% solo quando aumenta il consumo di memoria

Se vuoi monitorare l'utilizzo della memoria in base al processo (o al gruppo di nomi comuni condivisi elaborati, ad esempio google-chrome, puoi usare il mio script bash:

while true; do ps aux | awk ‚{print $5, $11}’ | grep chrome | sort -n > /tmp/a.txt; sleep 1; diff /tmp/{b,a}.txt; mv /tmp/{a,b}.txt; done;

questo cercherà continuamente le modifiche e le stamperà.

inserisci qui la descrizione dell'immagine


3

Se vuoi qualcosa di più veloce della profilazione con Valgrind e il tuo kernel è più vecchio e non puoi usare gli smaps, un ps con le opzioni per mostrare l'insieme residente del processo (con ps -o rss,command) può darti una veloce e ragionevole _aproximation_quantità reale di memoria non scambiata utilizzata.


3

Suggerirei di usare in cima. Puoi trovare tutto al riguardo in questa pagina . È in grado di fornire tutti i KPI necessari per i processi e può anche acquisire in un file.


2
Per mostrare il PSIZE ["dimensione della memoria proporzionale di questo processo (o utente)] avviare in atop -Ralto utilizzando . Per mostrare un push di riepilogo per utente p, per ordinare in base all'utilizzo della memoria premere 'M' dall'interno. Questo fornisce numeri simili a smem.
Markus Strauss,


1

Un altro voto per qui, ma vorrei aggiungere che puoi usare uno strumento come Alleyoop per aiutarti a interpretare i risultati generati da valgrind.

Uso sempre i due strumenti e ho sempre un codice snello e senza perdite per mostrarlo con orgoglio;)


1

Mentre questa domanda sembra riguardare l'esame dei processi attualmente in esecuzione, ho voluto vedere la memoria di picco utilizzata da un'applicazione dall'inizio alla fine. Oltre a valgrind, puoi usare tstime , che è molto più semplice. Misura l'utilizzo della memoria "highwater" (RSS e virtuale). Da questa risposta .


La maggior parte delle applicazioni, ovvero quelle che usano librerie di memoria malloc () e simili a malloc, non restituiscono le pagine al sistema operativo fino alla fine del processo. Quindi la quantità che vedi con PS (o qualsiasi altro strumento che non scava nell'heap del processo) sarà il massimo.
David C.

0

Basato sulla risposta a una domanda correlata .

È possibile utilizzare SNMP per ottenere la memoria e l'utilizzo della CPU di un processo in un determinato dispositivo in rete :)

Requisiti:

  • il dispositivo che esegue il processo dovrebbe avere snmp installato e in esecuzione
  • snmp dovrebbe essere configurato per accettare le richieste da dove eseguirai lo script di seguito (potrebbe essere configurato in snmpd.conf)
  • dovresti conoscere l'id di processo (pid) del processo che desideri monitorare

Appunti:

  • HOST-RESOURCES-MIB :: hrSWRunPerfCPU è il numero di centesimi di secondo delle risorse CPU del sistema totale consumate da questo processo. Si noti che su un sistema a più processori, questo valore può aumentare di oltre un centesimo di secondo in un centesimo di secondo del tempo reale (orologio da parete).

  • HOST-RESOURCES-MIB :: hrSWRunPerfMem è la quantità totale di memoria di sistema reale allocata a questo processo.

**

Script di monitoraggio del processo:

**

echo "IP: "
read ip
echo "specfiy pid: "
read pid
echo "interval in seconds:"
read interval

while [ 1 ]
do
    date
    snmpget -v2c -c public $ip HOST-RESOURCES-MIB::hrSWRunPerfCPU.$pid
    snmpget -v2c -c public $ip HOST-RESOURCES-MIB::hrSWRunPerfMem.$pid
    sleep $interval;
done

0

/ prox / xxx / numa_maps fornisce alcune informazioni lì: N0 = ??? N1 = ???. Ma questo risultato potrebbe essere inferiore al risultato effettivo, poiché conta solo quelli che sono stati toccati.


-1

Utilizzare lo strumento GUI integrato ' monitor di sistema ' disponibile in Ubuntu


1
Almeno dal 16.04 che funziona molto bene. È molto simile al top, tuttavia, la memoria utilizzata non è estremamente precisa ...
Alexis Wilke,
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.