Analisi della memoria Linux con comando libero e Pmap
Quando parliamo di memoria, allora sono i parametri più fraintesi dell’intero sistema, specialmente quando parliamo di Unix come sistema
Questo articolo parla principalmente di semplici strumenti che possono essere utilizzati per valutare l’utilizzo della memoria di un processo o di un sistema nel suo complesso.
Due aree principali sono la memoria del kernel e la memoria dell’utente, ora espandiamo un po’ questi termini.
Memoria del nocciolo
È la memoria gestita dal kernel che comprende:
• Testo — dove sono memorizzate solo le parti di sola lettura del programma. Questo è di solito il codice di istruzione effettivo del programma. Più istanze dello stesso programma possono condividere questa area di memoria.
• Dati statici: l’area in cui è allocata la memoria pre-nota. Questo è generalmente per variabili globali e membri di classi C++ statiche. Il sistema operativo alloca una copia di questa area di memoria per ogni istanza del programma.
• Memory arena (nota anche come spazio di pausa): l’area in cui è archiviata la memoria di runtime dinamica. L’arena della memoria è costituita da heap e memoria inutilizzata. L’heap è dove risiede tutta la memoria allocata dall’utente. L’heap cresce da un indirizzo di memoria inferiore a un indirizzo di memoria superiore.
• Stack — ogni volta che un programma effettua una chiamata di funzione, lo stato della funzione corrente deve essere salvato nello stack. Lo stack cresce da un indirizzo di memoria più alto a un indirizzo di memoria più basso. C’è un’arena di memoria e uno stack univoci per ogni istanza del programma.
Memoria utente
Risiede nell’heap della memoria ed è chiamato da routine di memoria come malloc(), realloc, free(), callo()
Quindi la memoria gioca un ruolo importante nelle prestazioni del sistema ed è uno dei componenti più critici da analizzare durante il problema delle prestazioni del sistema, abbiamo molti strumenti attraverso i quali è possibile misurare le prestazioni del sistema ma a volte fallisce miseramente soprattutto quando non si controlla un laboratorio domestico ma una macchina di produzione in esecuzione in modo critico con 60 G di RAM, processori multi-core e applicazioni pesanti che generano milioni di connessioni e quindi creano un collo di bottiglia delle prestazioni, in tali scenari l’esecuzione di comandi superiori sicuramente non rifletterà l’effettivo utilizzo della memoria e quindi in tali scenari scenari di solito non ci affidiamo troppo ai comandi ps o top perché riporta l’utilizzo della memoria del processo sul concetto che è l’unico processo in esecuzione sul sistema operativo del sistema, ma in realtà Linux ha anche alcuni concetti di libreria condivisa, quindi quando facciamo un ps o un sus su un processo da ottenere utilizzo, ignora altre cose relative alla memoria come sezioni condivise/private che mostrano l’effettivo utilizzo della memoria, questa riga qui sotto ci aiuterà a trovare le cose esatte per i processi in esecuzione.
Non dovresti sempre essere soddisfatto di questi top liner:
[redhat@localhost Desktop]$ ps -e -o user,pid,%cpu,%mem,rss,cmd --sort=-rss | head
USER PID %CPU %MEM RSS CMD
redhat 3114 4.2 1.1 21612 /usr/lib/vmware-tools/sbin32/vmtoolsd -n vmusr
root 2673 5.9 1.0 20032 /usr/bin/Xorg :0 -nr -verbose -audit 4 -auth /var/run/gdm/auth-for-gdm-WW9iey/database -nolisten tcp vt1
redhat 3090 5.3 0.9 18928 nautilus
redhat 3161 1.3 0.8 17444 /usr/bin/gnote --panel-applet --oaf-activate-iid=OAFIID:GnoteApplet_Factory --oaf-ior-fd=19
redhat 3207 3.4 0.7 14384 /usr/bin/gnome-terminal -x /bin/sh -c cd '/home/redhat/Desktop' && exec $SHELL
redhat 3162 1.2 0.6 13084 /usr/libexec/clock-applet --oaf-activate-iid=OAFIID:GNOME_ClockApplet_Factory --oaf-ior-fd=28
redhat 3084 0.8 0.5 11620 gnome-panel
redhat 3146 0.7 0.5 11176 nm-applet --sm-disable
redhat 3133 0.4 0.5 10428 gnome-volume-control-applet
NB: The moral of this story is that process memory usage on Linux is a complex matter; you can't just run ps and know what is going on. This is especially true when you deal with programs that create a lot of identical children processes, like Java. Ps command might report that each Java process uses 100 megabytes of memory, when the reality might be that the marginal cost of each Java process is 10 megabyte of memory.
Una riga qui sotto ti darà un quadro dettagliato di cosa sta succedendo sotto le lenzuola:
for i in `ps -eaf | grep java | grep -v grep | awk '{print $2}'`; do echo -n "PID $i actual memory usage is :" >> totaluse.txt; pmap -d $i | grep -i "writeable/private: " >> totaluse.txt; done
Ora non lasciarti spaventare da quella battuta perché la suddividerò in pezzi per spiegarne ogni parte e poi potrai vedere quanto sia facile usare tali liner in alcuni degli scenari di produzione più critici, qui noi parlato dello strumento pmap, introduciamo pmap e definiamolo ufficialmente secondo la pagina MAN:
NAME
PMAP - REPORT MEMORY MAP OF A PROCESS
SYNOPSIS
PMAP [ -X | -D ] [ -Q ] PIDS...
PMAP -V
DESCRIPTION
THE PMAP COMMAND REPORTS THE MEMORY MAP OF A PROCESS OR PROCESSES.
GENERAL OPTIONS
-X EXTENDED SHOW THE EXTENDED FORMAT.
-D DEVICE SHOW THE DEVICE FORMAT.
-Q QUIET DO NOT DISPLAY SOME HEADER/FOOTER LINES.
-V SHOW VERSION DISPLAYS VERSION OF PROGRAM.
EXTENDED AND DEVICE FORMAT FIELDS
ADDRESS: START ADDRESS OF MAP
KBYTES: SIZE OF MAP IN KILOBYTES
RSS: RESIDENT SET SIZE IN KILOBYTES
DIRTY: DIRTY PAGES (BOTH SHARED AND PRIVATE) IN KILOBYTES
MODE: PERMISSIONS ON MAP: READ, WRITE, EXECUTE, SHARED, PRIVATE (COPY ON WRITE)
MAPPING: FILE BACKING THE MAP, OR ’[ ANON ]’ FOR ALLOCATED MEMORY, OR ’[ STACK ]’ FOR THE PROGRAM STACK
OFFSET: OFFSET INTO THE FILE
DEVICE: DEVICE NAME (MAJOR:MINOR)
Quindi possiamo visualizzare la mappa del processo di qualsiasi processo e il suo effettivo consumo di memoria e non la vaga media riportata dal processo principale, prenderò uno scenario di produzione per spiegare la mia linea sopra e altri calcoli di memoria basati su strumenti di memoria, come free .
Scenarios : its difficult to find the actual memory consumption as top is reporting memory usage is 98% utilized and free is also aligning with the top output with no process running in the system other than the system processes, what could be the reason and how to debug it.
Filosofia Linux
La filosofia in Linux è che una risorsa inutilizzata è una risorsa sprecata. Pertanto, il kernel utilizzerà quanta più RAM possibile per memorizzare nella cache le informazioni sui file system e sui dischi locali e remoti. Questo si accumula nel tempo man mano che vengono eseguite letture e scritture sul sistema, cercando di mantenere i dati archiviati nella RAM il più pertinenti possibile ai processi in esecuzione sul sistema. Questa cache viene segnalata dal sistema come la somma di due numeri, buffer e pagecache. La cache viene recuperata, non quando il processo termina (potresti presto avviare un altro processo che richiede gli stessi dati), ma su richiesta, ad esempio quando avvii un processo che richiede molta memoria per essere eseguito, il kernel di Linux recupererà la memoria che aveva memorizzato nella cache i dati e darli al nuovo processo.
Detto questo, ci sono alcune cose che vengono segnalate come “memorizzate nella cache” ma non direttamente disponibili per il kernel:
1. mmap anonime, che non sono supportate da un file ma dall’area di scambio.
2. regioni di memoria condivise, sia System V IPC che POSIX /dev/shm.
3. Alcuni server di applicazioni e database (ad esempio SAP e Oracle DB) utilizzano queste strutture di memoria condivisa come un modo molto conveniente per condividere i dati tra più processi.
Sebbene sia le mmap anonime che le regioni di memoria condivisa possano essere scambiate dalla memoria al disco, quindi le tue applicazioni potrebbero teoricamente utilizzare quella memoria, il tuo sistema potrebbe riscontrare problemi di prestazioni se questo appare.
Di conseguenza, se il tuo sistema utilizza una delle funzionalità di cui sopra, dovresti notare che non tutta la memoria indicata come “cache” dovrebbe essere considerata disponibile per le tue applicazioni.
Continueranno a segnalare tutti i processi ad essi collegati, a differenza della normale cache che non fa parte dello spazio degli indirizzi di alcun processo in esecuzione, ma è semplicemente una mappatura del kernel.
Ad esempio (le unità sono in megabyte):
# free -m
total used free shared buffers cached
Mem: 1000 900 100 0 350 350
-/+ buffers/cache: 200 800
In questo esempio, in termini di applicazioni, il sistema utilizza solo 200 MB di memoria e dispone di 800 MB liberi e disponibili per l’uso se necessario (purché non vi siano mappe di memoria anonime o aree di memoria condivise).
Nota: in questo esempio,
Total Physical Memory = 1000 M
Physically Used Memory = 900 M
Actual used memory = 200 M
buffers = 350 M
cached = 350 M
Physically Free Memory = 100 M
Memory free for Applications = 800 M
Gli elementi da notare qui sono:
<Physically Used Memory> = <Actual used memory> + <buffers> + <cache> = 200 + 350 + 350 = 900 M
<Physically Free Memory> = <Total Physical Memory> - <Actual used memory> - <buffers> - <cache> = 1000 - 200 - 350 - 350 = 100 M
<Memory free for Applications> = <Total Physical Memory> - <Actual used memory> = 1000 - 200 = 800 M
<Memory used by Applications> = <Physically Used Memory> - <buffers> - <cache> = 900 - 350 - 350 = 200 M
Lo scenario di cui sopra spiega un perfetto esempio di utilizzo gratuito dello strumento, perché la comprensione di ogni parametro del risultato può portare a conclusioni sorprendenti e ridurre il capitale totale delle spese di aggiornamento del server.
Possiamo spiegare un po ‘di one-liner qui ora, nel caso in cui sia necessaria la mappa dettagliata del processo per i calcoli di cui sopra, è richiesto un po’ di scripting della shell bash e puoi ottenere valori “fuori scala” per le prestazioni del tuo sistema, diamo un’occhiata alla spiegazione di seguito, la visualizzazione della mappa dei processi per ciascun processo di sistema può essere ottenuta con questa riga, quindi è possibile aggiungere le sezioni seguenti per ottenere l’utilizzo della memoria di sistema o dell’applicazione, se si desidera evitare i calcoli di libero strumenti di cui sopra.
Utilizzando Pmap
for i in `ps -eaf | grep “any application process” | grep -v grep | awk '{print $2}'`; do echo -n "PID $i actual memory usage is :" >> totaluse.txt; pmap -d $i | grep -i "writeable/private: " >> totaluse.txt; done
Ora lo stesso parametro “Memoria utilizzata dalle applicazioni” può essere confermato due volte con sopra anche se hai tempo e vuoi una spiegazione precisa dell’utilizzo della memoria da parte dell’applicazione o del processo di sistema, quindi facendo un gatto su totaluse.txt, vedrai qualcosa di simile questo:
{di seguito è solo un esempio e non ha nulla a che fare con il calcolo precedente}
PID 16156 actual memory usage is :mapped: 15128K writeable/private: 10824K shared: 28K
PID 16158 actual memory usage is :mapped: 1381472K writeable/private: 1349680K shared: 2676K
PID 20220 actual memory usage is :mapped: 15196K writeable/private: 10892K shared: 28K
PID 20222 actual memory usage is :mapped: 2733700K writeable/private: 2708256K shared: 2932K
PID 27764 actual memory usage is :mapped: 15196K writeable/private: 10892K shared: 28K
PID 27766 actual memory usage is :mapped: 277176K writeable/private: 255552K shared: 3360K
Ora se aggiungi le sezioni scrivibili/private otterrai esattamente l’utilizzo della memoria dei processi IV, spero che questo aiuti. Aggiungendo queste colonne si arriva vicino a 4+GB, 10824+1349680+10892+2708256+10892+255552 KB di memoria === vicino a 4+GB.
In conclusione, qui abbiamo discusso di free e pmap per ottenere l’esatto utilizzo della memoria ed evitare vaghi risultati migliori in scenari di produzione critici.