Q&A #1: Leggere le statistiche di memoria e individuare i rallentamenti del sistema
Il primo argomento del Q&A ce lo propone Avatar. Vi ricordo che potete inviare le vostre richieste compilando il form in questa pagina. Il prossimo Q&A è per sabato prossimo.
La domanda di Avatar è come leggere ed interpretare i dati proposti dalle utility top (da terminale) e Monitoraggio Attività, e perchè a volte il nostro Mac si congela per qualche secondo senza un apparente motivo.
Prima di entrare nel vivo dell’argomento è necessario però fare qualche premessa sul funzionamento della memoria nei sistemi operativi moderni. Se i termini memoria fisica e virtuale non vi sono sconosciuti siete liberi di saltare il paragrafo che segue.
Come funziona la memoria
A livello hardware la memoria è costituita da un insieme di chip su cui viene memorizzato uno dei due stati logici possibili (1,0). Possiamo immaginare la memoria del nostro computer come una grande matrice in cui le celle sono identificate univocamente dal relativo numero di riga e di colonna; riga e colonna costituiscono insieme l’indirizzo della cella su cui il sistema operativo può operare (nella realtà ovviamente gli OS non accederanno mai ai singoli byte ma opereranno su porzioni ben maggiori di indirizzi alla volta).
Tra il sistema operativo e l’hardware di memoria troviamo una serie di componenti fondamentali della CPU che vanno sotto il nome di MMU, Memory Managment Unit.
MMU si occupa di gestire le richieste di accesso alla memoria rendendo possibile l’uso di quella che viene chiamata memoria virtuale.
La memoria virtuale è una architettura che permette ad un sistema operativo di simulare l’esistenza di una spazio di memoria maggiore rispetto a quello realmente disponibile in RAM. Questo risultato viene raggiunto attingendo ad unità di immagazzinamento secondarie – come gli hard disk. In questo modo una parte dell’hard disk entra a far parte della memoria disponibile al sistema operativo e/o ai programmi che ne fanno richiesta (in realtà tutte le richieste di memoria dei programmi sono filtrate e gestite in maniera trasparente dall’OS; in questo modo i programmi non vedono differenza tra i due tipi di memoria poichè fanno riferimento ad un set di indirizzi detto virtuale).
L’MMU si occuperà poi di tradurre questi indirizzi virtuali in indirizzi fisici, attingendo di volta in volta o alla memoria RAM o a quella ausiliaria (chiameremo questo tipo memoria swap, e l’azione corrispondente è swapping).
In un sistema operativo del genere il processore e i programmi si riferiscono infatti ad indirizzi logici virtuali che poi vengono automaticamente tradotti in indirizzi fisici proprio grazie alla mediazione della MMU.
Nel dettaglio l’MMU controlla che se l’indirizzo richiesto corrisponde ad una parte della memoria centrale o alla swap; in questo ultimo caso solleverà una eccezione che va sotto il nome di page fault e che deve essere gestita dal sistema operativo.
Come già detto questa gestione deve essere eseguita in maniera trasparente verso programma (cioè come se non fosse accaduto nessun fault), caricando (o scrivendo) la zona richiesta e mettendola infine a disposizione.
Un insieme di programmi possono anche condividere una stessa zona di memoria; ad esempio, in OS X, la zona che contiene il framework AppKit (ovvero l’insieme di funzioni e controlli per la UI – come pulsanti, liste, controllo browser etc) viene condivisa da tutti i programmi. La condivisione di spazi di memoria (in gergo ‘shared memory‘) è un elemento molto importante che permette al sistema operativo di risparmiare spazio sulla memoria evitando di caricare gli stessi dati più volte.
Entrambe le tecniche possono essere combinate; così questi framework condivisi sono caricati nel momento in cui effettivamente servono (lazily) e sono messi a disposizione di più programmi.
Come leggere Monitoraggio Attività/top
Dopo questa breve, ma necessaria introduzione possiamo definire alcuni dei termini legati alla memoria (per chiarezza li lascerò nella loro forma inglese):
- Resident: è la zona di memoria localizzata della RAM fisica
- Private: è la zona di memoria che appartiene ad uno e un solo processo
- Shared: è la zona di memoria che viene condivisa da più processi
- Address Space Size: la quantità di spazio di indirizzamento occupato da una particolare sezione della memoria virtuale
- Memory Size: è il quantitativo di memoria fisica occupato
e gli altri indicati dal comando top:
- RPRVT: la quantitò di address space, relativo al processo, che corrisponde ad elementi attualmente presenti nella RAM
- RSHRD: la quantità di address space, condivisa tra il processo e almeno un altro processo, che corrisponde ad elementi presenti attualmente in RAM
- RSIZE: la quantità totale di RAM utilizzata dal processo (che non è RPRVT+RSHRD perchè questi misurano lo spazio di indirizzamento)
- VPRVT: la quantità di address space non condivisa con altri processi
- VSIZE: la dimenzione totale di address space mappata con qualsiasi altro elemento

(E’ da notare che i valori riportati non sono esatti ma soltanto approssimativi)
Per i programmi che utilizzano uno spazio di indirizzamento a 32-bit VSIZE è un elemento molto importante perchè è limitato a 4GB; superato questo limite le successive allocazioni richieste vengono scartate e molto probabilmente si andrà verso un imminente crash del processo. Quindi un valore di VSIZE molto prossimo ai 4GB va inteso come un alto consumo degli spazio di indirizzamento disponibili per il processo.
Per processi a 64-bit il limite è virtualmente infinito (64GB) ed è possibile ignorare tranquillamente questo valore.
RPRVT è un buon indicatore per verificare l’andamento sul consumo di memoria del programma. E’ tuttavia necessario considerare che il processo in questione potrebbe andare in swap (utilizzando quindi la memoria virtuale); in questo caso RPRVT non riporterebbe l’esatto andamento di memoria (dovremmo verificare se VPRVT e il numero di pageouts aumentano).
Tuttavia per verificare esattamente il consumo di memoria e gli eventuali leaks di un programma (fasi in cui non vengono correttamente rilasciate al sistema operativo porzioni di RAM non più in uso) è necessario usare tools come leaks o ObjectAlloc (nel 10.6 il relativo template di Instruments).
Individuare le cause di rallentamento
A volte capita che il nostro Mac rallenti o si “congeli” per qualche secondo mentre la funesta beachball ruota (… e non è la sola cosa). In questo caso si tende erroneamente a pensare che sia tutta colpa della mancanza di RAM. In realtà questa affermazione è vera solo a metà: i problemi di rallentamento sono dovute ad azioni di I/O (input/output), ovvero di operazioni di lettura/scrittura su disco. Sebbene in alcuni casi l’I/O sia richiesto dalle operazioni di swapping (che accadono in caso di mancanza di sufficiente memoria RAM), in molti altri casi si tratta semplicemente di processi che tendono a fare un uso eccessivo e indiscriminato dell’accesso a disco (processi di questo tipo sono ad esempio Time Machine o Spotlight).
Per verificare in maniera dettagliata quale processo sta occupando il disco dobbiamo però ricorrere al terminale: basterà digitare il comando
> sudo iotop -P
e dopo aver inserito la password di utente potrete vedere una schermata del genere (qui due sottoprocessi del Finder utilizzano quasi l’intero spazio di I/O disponibile).
Al prossimo sabato! (potete proporre il vostro argomento cliccando qui)
