La memoria “cache” è di fatto gratuita?


11

Durante l'esecuzione cat /proc/meminfo, ottieni questi 3 valori in alto:

MemTotal:        6291456 kB
MemFree:         4038976 kB
Cached:          1477948 kB

Per quanto ne so, il valore "Cache" è la cache del disco creata dal sistema Linux che verrà liberata immediatamente se qualsiasi applicazione necessita di più RAM, quindi Linux non esaurirà mai la memoria fino a quando sia MemFree che Cache sono a zero.

Sfortunatamente, "MemAvailable" non è segnalato da / proc / meminfo, probabilmente perché è in esecuzione in un server virtuale. (La versione del kernel è 4.4)

Pertanto, per tutti gli scopi pratici, la RAM disponibile per le applicazioni è MemFree + cache.

Quella vista è corretta?


1
Non voglio martellare in questo modo chiuso, ma questa domanda è rilevante se non un duplicato. Sono sorpreso che tu non l'abbia fatto MemAvailable, è stato aggiunto in 3.14.
Stephen Kitt,

La risposta accettata da quella domanda usa / proc / zoneinfo, che non è disponibile anche sul mio
server virtuale

uname -a: host Linux 4.4.0-042stab134.8 # 1 SMP ven 7 dic 17 17:16:09 MSK 2018 x86_64 x86_64 x86_64 GNU / Linux
Roland Seuhs

Ho il sospetto che questo sia un sistema OpenVZ con un kernel che si basa davvero su 2.6.32, non 4.4.
Stephen Kitt,

1
@sourcejedi ed è stato compilato esattamente nello stesso momento del kernel 4.4!
Stephen Kitt,

Risposte:


10

Tale opinione può essere molto fuorviante in numerosi casi del mondo reale.

Il kernel ora fornisce una stima della memoria disponibile, sul MemAvailablecampo. Questo valore è significativamente diverso da MemFree + Cached.

/ proc / meminfo: fornisce la memoria disponibile stimata [descrizione della modifica del kernel, 2014]

Molti programmi di bilanciamento del carico e posizionamento del carico di lavoro controllano / proc / meminfo per stimare la quantità di memoria disponibile disponibile. Generalmente lo fanno aggiungendo "libero" e "memorizzato nella cache", che andava bene dieci anni fa, ma oggi è praticamente garantito che si sbaglia.

È errato perché nella cache è inclusa una memoria che non può essere liberata come cache di pagina, ad esempio segmenti di memoria condivisa, tmpfs e ramfs, e non include memoria slab recuperabile, che può occupare una grande parte della memoria di sistema su sistemi prevalentemente inattivi con molti file.

Attualmente, la quantità di memoria disponibile per un nuovo carico di lavoro, senza spostare il sistema in scambio, può essere stimata da MemFree, Active (file), Inactive (file) e SReclaimable, nonché dalle filigrane "basse" da / proc / zoneinfo. Tuttavia, questo potrebbe cambiare in futuro e lo spazio utente non dovrebbe essere in grado di conoscere gli interni del kernel per elaborare una stima della quantità di memoria libera. È più conveniente fornire tale stima in / proc / meminfo. Se le cose cambieranno in futuro, dovremo cambiarle in un solo posto.
...

Documentation / filesystems / proc.txt:
...
MemAvailable: una stima della quantità di memoria disponibile per l'avvio di nuove applicazioni, senza scambio. Calcolato da MemFree, SReclaimable, la dimensione degli elenchi LRU del file e le filigrane basse in ciascuna zona. La stima tiene conto del fatto che il sistema ha bisogno di alcune cache di pagina per funzionare correttamente e che non tutti i pannelli recuperabili saranno recuperabili, a causa degli oggetti in uso. L'impatto di tali fattori varia da sistema a sistema.

1. MemA dettagli disponibili

Come detto sopra, tmpfs e altra Shmemmemoria non possono essere liberati, ma solo spostati in swap. Cachedin /proc/meminfopuò essere molto fuorviante, a causa dell'inclusione di questa Shmemmemoria sostituibile . Se hai troppi file in un tmpfs, potrebbe occupare molta memoria :-). Shmempuò anche includere alcune allocazioni di memoria grafica , che potrebbero essere molto grandi.

MemAvailabledeliberatamente non include memoria sostituibile. Lo scambio eccessivo può causare lunghi ritardi. Potresti anche aver scelto di correre senza spazio di swap o consentire solo un importo relativamente limitato.

Ho dovuto ricontrollare come MemAvailablefunziona. A prima vista, il codice non sembra menzionare questa distinzione.

/*
 * Not all the page cache can be freed, otherwise the system will
 * start swapping. Assume at least half of the page cache, or the
 * low watermark worth of cache, needs to stay.
 */
pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE];
pagecache -= min(pagecache / 2, wmark_low);
available += pagecache;

Tuttavia, l'ho trovato correttamente tratta Shmemcome memoria "usata". Ho creato diversi file da 1 GB in un tmpfs. Ogni aumento di 1 GB viene Shmemridotto MemAvailabledi 1 GB. Pertanto, la dimensione degli "elenchi LRU dei file" non include la memoria condivisa o qualsiasi altra memoria scambiabile. (Ho notato che questi stessi conteggi di pagine vengono utilizzati anche nel codice che calcola il "limite sporco" ).

Questo MemAvailablecalcolo presuppone anche che si desideri mantenere almeno una quantità sufficiente di cache dei file per eguagliare la "filigrana bassa" del kernel. O metà della cache corrente, a seconda di quale è più piccola. (Fa lo stesso presupposto anche per le lastre recuperabili). La "filigrana bassa" del kernel può essere ottimizzata, ma di solito è circa il 2% della RAM di sistema . Quindi, se vuoi solo una stima approssimativa, puoi ignorare questa parte :-).

Quando si esegue firefoxcon circa 100 MB di codice programma mappato nella cache della pagina, in genere si desidera mantenere quei 100 MB nella RAM :-). Altrimenti, nella migliore delle ipotesi subirai ritardi, nella peggiore delle ipotesi il sistema passerà tutto il suo tempo a battere tra le diverse applicazioni. Quindi MemAvailablesta permettendo una piccola percentuale di RAM per questo. Potrebbe non consentire abbastanza o potrebbe essere troppo generoso. "L'impatto di questi fattori varierà da sistema a sistema".

Per molti carichi di lavoro su PC, il punto su "molti file" potrebbe non essere pertinente. Anche così, al momento ho una memoria slab recuperabile da 500 MB sul mio laptop (su 8 GB di RAM). Ciò è dovuto a ext4_inode_cache(oltre 300.000 oggetti). È successo perché di recente ho dovuto scansionare l'intero filesystem, per trovare cosa stava usando il mio spazio su disco :-). Ho usato il comando df -x / | sort -n, ma ad esempio Gnome Disk Usage Analyzer avrebbe fatto la stessa cosa.

2. [modifica] Memoria nei gruppi di controllo

I cosiddetti "contenitori di Linux" sono costruite da namespaces, cgroupse varie altre caratteristiche a seconda dei gusti :-). Possono fornire un ambiente abbastanza convincente per eseguire qualcosa di simile a un sistema Linux completo. I servizi di hosting possono creare container come questo e venderli come "server virtuali" :-).

I server di hosting possono anche creare "server virtuali" utilizzando funzionalità che non sono presenti in Linux. I contenitori OpenVZ pre-datano i cgroup mainline di due anni e possono utilizzare "beancounters" per limitare la memoria. Quindi non puoi capire esattamente come funzionano questi limiti di memoria se leggi solo documenti o fai domande sul kernel principale di Linux. cat /proc/user_beancountersmostra l'utilizzo e i limiti attuali. vzubclo presenta in un formato leggermente più amichevole. La pagina principale su beancounters documenta i nomi delle righe.

I gruppi di controllo includono la possibilità di impostare limiti di memoria sui processi al loro interno. Se esegui l'applicazione all'interno di un tale cgroup, non tutta la memoria di sistema sarà disponibile per l'applicazione :-). Quindi, come possiamo vedere la memoria disponibile in questo caso?

L'interfaccia per questo differisce in vari modi, a seconda che tu usi cgroup-v1 o cgroup-v2 .

L'installazione del mio laptop utilizza cgroup-v1. Posso correre cat /sys/fs/cgroup/memory/memory.stat. Il file mostra vari campi tra cui total_rss, total_cache, total_shmem. shmem, incluso tmpfs, conta ai fini dei limiti di memoria. Immagino che tu possa vedere total_rssun equivalente inverso di MemFree. E c'è anche il file memory.kmem.usage_in_bytes, che rappresenta la memoria del kernel inclusi i slab. (Presumo memory.kmem.includa anche memory.kmem.tcp.e eventuali estensioni future, anche se questo non è documentato esplicitamente). Non ci sono contatori separati per visualizzare la memoria della lastra recuperabile. Il documento per cgroup-v1 dice che colpire i limiti di memoria non provoca il recupero di alcuna memoria slab. (Il documento ha anche una dichiarazione di non responsabilità che è "irrimediabilmente obsoleto" e che è necessario controllare il codice sorgente corrente).

cgroup-v2 è diverso. Penso che il cgroup radice (di livello superiore) non supporti la contabilità della memoria. cgroup-v2 ha ancora un memory.statfile. Tutti i campi si sommano su cgroups secondari, quindi non è necessario cercare total_...campi. C'è un filecampo, il che significa che ha fatto la stessa cosa cache. Purtroppo non vedo un campo generale come rssall'interno memory.stat; Immagino che dovresti aggiungere singoli campi. Esistono statistiche separate per la memoria della lastra recuperabile e non reclamabile; Penso che un cgroup v2 sia progettato per recuperare lastre quando inizia a esaurire la memoria.

I cgroup di Linux non si virtualizzano automaticamente /proc/meminfo(o nessun altro file in /proc), quindi ciò mostrerebbe i valori per l'intera macchina. Ciò confonderebbe i clienti VPS. Tuttavia è possibile utilizzare gli spazi dei nomi per sostituirli /proc/meminfocon un file falsificato dal software contenitore specifico . L'utilità dei valori falsi dipende da ciò che fa quel software specifico.

systemdritiene che cgroup-v1 non possa essere delegato in modo sicuro, ad esempio ai container. Ho guardato dentro un systemd-nspawncontenitore sul mio sistema cgroup-v1. Riesco a vedere il cgroup in cui è stato inserito e la memoria che conta su quello. D'altra parte il contenuto systemdnon imposta i soliti cgroup per servizio per la contabilità delle risorse. Se l'account di memoria non fosse abilitato all'interno di questo cgroup, suppongo che il contenitore non sarebbe in grado di abilitarlo.

Suppongo che se sei all'interno di un contenitore cgroup-v2, avrà un aspetto diverso dalla radice di un vero sistema cgroup-v2 e sarai in grado di vedere la memoria che conta per il suo cgroup di livello superiore. O se il cgroup che vedi non ha l'account di memoria abilitato, spero che ti verrà delegata l'autorizzazione in modo da poter abilitare l'account di memoriasystemd (o equivalente).



1
è clicko nao. Uso i collegamenti GitHub perché mostrano la prima versione che contiene il commit (simile a git describe --contains). L'ho trovato collegato come TL; DR da una domanda SU, che si è rivelata solo citando la sezione aggiunta a proc.txt. Ma per questa domanda, la descrizione del commit è semplicemente perfetta IMO :-).
sourcejedi,

MemAvailable non sembra essere disponibile sulla maggior parte dei server virtuali ... cosa fare allora?
Roland Seuhs,

@RolandSeuhs probabilmente impara "beancounters". Vedi le modifiche in grassetto. Se hai una domanda sui beancounters, ti sarei grato se facessi una nuova domanda. Possiamo sempre collegarci ad esso da questo, ma i dettagli probabilmente non sono rilevanti per tutti i lettori che usano un kernel Linux mainline.
FonteJedi
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.