Come misurare l'utilizzo effettivo della memoria di un'applicazione o di un processo?
Domanda
Questa domanda è trattata qui in dettaglio.
Come si misura l'utilizzo della memoria di un'applicazione o processo in Linux?
Dall'articolo del blog di Comprensione dell'utilizzo della memoria su Linux , ps
non è uno strumento preciso da utilizzare per questo scopo.
Perché
ps
è " errato "A seconda di come lo si guarda,
ps
non sta segnalando 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 dozzine di processi in esecuzione in un dato momento, il che significa che i numeri VSZ e RSS riportati daps
sono quasi sicuramente errati .
Soluzione
Con ps
o 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 per 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, valgrind
può fornire informazioni sulla quantità di memoria utilizzata e, cosa ancora più importante, su possibili perdite di memoria nel programma. Lo strumento di profilatura 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 valgrind , è necessario eseguire il programma valgrind:
valgrind --tool=massif <executable> <arguments>
Massif scrive un dump di istantanee sull'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 eccezionale strumento grafico per l'analisi di questi file è massif-visualizer . Ma ho trovato ms_print
, un semplice strumento basato su testo fornito con valgrind, già di grande aiuto.
Per trovare perdite di memoria, usa lo strumento (predefinito) memcheck
di valgrind.
Altri suggerimenti
Prova il comando pmap :
sudo pmap -x <process pid>
Difficile dirlo con certezza, ma qui ci sono due "chiudi" cose 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 aux
dà.
/proc/19420$ cat status Name: firefox State: S (sleeping) Tgid: 19420 Pid: 19420 PPid: 1 TracerPid: 0 Uid: 1000 1000 1000 1000 Gid: 1000 1000 1000 1000 FDSize: 256 Groups: 4 6 20 24 25 29 30 44 46 107 109 115 124 1000 VmPeak: 222956 kB VmSize: 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 Threads: 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
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.
Non esiste un modo semplice per calcolare questo. Ma alcune persone hanno cercato di ottenere delle buone risposte:
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 la memoria unica ). Non include la memoria condivisa. Pertanto, in verrà riportato la quantità di memoria utilizzata da un processo, ma è utile quando si desidera ignorare la memoria condivisa.
PSS - Dimensioni set proporzionale. Questo è quello che vuoi. Aggiunge la memoria unica (USS), insieme a una parte della sua memoria condivisa divisa per il numero di altri 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 al P che sta per memoria fisica .
Come 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 qualche processo condivide la memoria, questo over -segnalerà la quantità di memoria effettivamente utilizzata, perché la stessa memoria condivisa verrà contata più di una volta - riapparendo in ogni altro processo che condivide la stessa memoria. Quindi è abbastanza inaffidabile, specialmente quando i processi ad alta memoria hanno un sacco di fork - cosa comune in un server, con cose 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.
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]
Che dire di time
?
Non Bash incorporato time
ma quello che puoi trovare con che ora
, ad esempio / usr / bin / time
Ecco cosa copre, su un 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
Questo è un eccellente riassunto degli strumenti e dei problemi: collegamento archive.org
Lo citerò, in modo che più sviluppatori lo leggano effettivamente.
Se desideri analizzare l'utilizzo della memoria dell'intero sistema o analizzare in modo approfondito l'utilizzo della memoria di un'applicazione (non solo il suo utilizzo dell'heap), usa exmap . Per l'analisi dell'intero sistema, trovano processi con il massimo utilizzo efficace, 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 vuoi rilevare perdite, usa valgrind o possibilmente kmtrace .
Se desideri analizzare l'utilizzo dell'heap (malloc ecc.) di un'applicazione, eseguilo in memprof o con kmtrace , profila l'applicazione e cerca la chiamata di funzione albero per le maggiori allocazioni. Vedi le loro sezioni per maggiori dettagli.
Oltre alle soluzioni elencate nelle tue risposte, puoi utilizzare il comando Linux "top" Fornisce una visualizzazione dinamica in tempo reale del sistema in esecuzione, fornisce l'utilizzo della CPU e della memoria, per l'intero sistema e per ogni programma, in percentuale:
top
per filtrare in base a un programma pid:
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.
DATI - Dati + Dimensione dello stack (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 .
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'altro canto, valgrind offre un profilo migliore dell'utilizzo della memoria per tutta la durata del programma
Se il tuo codice è in C o C ++ potresti essere in grado di usare getrusage ()
che ti restituisce varie statistiche sulla memoria e sull'utilizzo del tempo del tuo processo.
Tuttavia, non tutte le piattaforme supportano questo e restituiranno 0 valori per le opzioni di utilizzo della memoria.
Invece puoi guardare il file virtuale creato in / proc / [pid] / statm
(dove [pid]
è sostituito dal tuo ID di processo. Puoi ottenere questo 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.
Valgrind può mostrare informazioni dettagliate ma rallenta l'applicazione di destinazione in modo significativo e la maggior parte delle volte cambia 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 WRT " utilizzo della memoria " è il seguente ...
In Linux, la quantità di memoria fisica che un singolo processo potrebbe usare può essere approssimativamente suddivisa nelle seguenti categorie.
M.a memoria mappata anonima
- .p privato
- .d dirty == malloc / mmapped heap e stack allocati e memoria scritta
- .c clean == malloc / mmapped heap e memoria stack una volta allocata, scritta, quindi liberata, ma non ancora recuperata
- .s condiviso
- .d dirty == heap malloc / mmaped potrebbe essere copiato e condiviso tra i processi (modificato)
- .c clean == hallo malloc / mmaped potrebbe essere copiato e condiviso tra i processi (modificato)
- .p privato
Memoria mappata denominata M.n
- .p privato
- .d dirty == file mmapped memoria scritta privata
- .c clean == testo del programma / libreria mappato privato mappato
- .s condiviso
- .d dirty == file ha scritto la memoria scritta condivisa
- .c clean == testo della libreria mappato condiviso mappato
- .p privato
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
Sto usando htop
; è un ottimo programma console simile a Task Manager di Windows.
Valgrind è fantastico se hai il tempo di eseguirlo. valgrind --tool = massif
è la soluzione giusta.
Tuttavia, sto iniziando a dare esempi più ampi e l'uso di valgrind non è più pratico. C'è un modo per dire il massimo utilizzo di memoria (dimensione della pagina modulo e pagine condivise) di un programma?
Su un sistema unix reale, / usr / bin / time -v
funziona. Su Linux, tuttavia, questo non funziona.
Altri tre metodi da provare:
-
ps aux --sort pmem
Ordina l'output per% MEM
. -
ps aux | awk '{stampa $ 2, $ 4, $ 11}' | ordina -k2r | head -n 15
Si ordina usando i tubi. -
top -a
Inizia l'ordinamento principale per%MEM
(estratto da qui )
#!/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
Un buon test del più "mondo reale" l'uso è quello di aprire l'applicazione, quindi eseguire vmstat -s
e controllare la "memoria attiva" statistica. Chiudi l'applicazione, attendi qualche secondo ed esegui nuovamente vmstat -s
. Tuttavia, molta memoria attiva liberata era evidentemente in uso dall'app.
Se il processo non consuma troppa memoria (o perché ci si aspetta 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, può provare a usare il comando gcore.
gcore <pid>
Controlla la dimensione del file core generato per avere una buona idea di quanta memoria sta usando un particolare processo.
Questo non funzionerà troppo bene se il processo utilizza centinaia di mega 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 "bloccato") per impedire modifiche alla memoria. Quindi fai attenzione.
Assicurati anche 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.
Sotto la riga di comando troverai la memoria totale utilizzata 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}'
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
=============================================
Ottieni valgrind. dagli il tuo programma da eseguire e ti dirà molto sull'utilizzo della memoria.
Ciò si applicherebbe solo al 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.
Modifica: funziona bene al 100% solo quando aumenta il consumo di memoria
Se desideri monitorare l'utilizzo della memoria in base al processo (o al gruppo di nome comune condiviso elaborato, ad esempio google-chrome
, puoi utilizzare 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à.
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 il set residente del processo (con ps -o rss, comando
) può fornirti un _aproximation_
rapido e ragionevole della quantità reale di memoria non scambiata utilizzata.
Suggerirei di utilizzare in cima. Puoi trovare tutto al riguardo su questa pagina . È in grado di fornire tutti i KPI necessari per i tuoi processi e può anche acquisire in un file.
Controlla lo script della shell per controllare utilizzo della memoria per applicazione in linux . Disponibile anche su github e in una versione senza incolla e bc .
Mentre questa domanda sembra riguardare l'esame dei processi attualmente in esecuzione, volevo vedere la memoria di picco utilizzata da un'applicazione dall'inizio alla fine. Oltre a valgrind, puoi utilizzare tstime , che è molto più semplice. Misura "acqua alta" utilizzo della memoria (RSS e virtuale). Da questa risposta .
Utilizza lo strumento GUI integrato monitor di sistema 'disponibile in Ubuntu
Basato sulla risposta a un domanda .
È possibile utilizzare SNMP per ottenere memoria e utilizzo della CPU di un processo in un determinato dispositivo in rete :)
Requisiti:
- sul dispositivo che esegue il processo dovrebbe essere installato e in esecuzione snmp
- snmp deve 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 vuoi monitorare
Note:
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