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

StackOverflow https://stackoverflow.com/questions/131303

  •  02-07-2019
  •  | 
  •  

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 da ps sono quasi sicuramente errati .

È stato utile?

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)
  • 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

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:

  1. ps aux --sort pmem
    Ordina l'output per % MEM .
  2. ps aux | awk '{stampa $ 2, $ 4, $ 11}' | ordina -k2r | head -n 15
    Si ordina usando i tubi.
  3. 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à.

inserisci qui la descrizione dell'immagine

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 .

Un altro voto per qui, ma io vorrei aggiungere che puoi utilizzare 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;)

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top