GNU/Linux >> Linux Esercitazione >  >> Linux

Effetti della configurazione di vm.overcommit_memory

Soluzione 1:

Impostazione overcommit_ratio a 80 probabilmente non è l'azione giusta. L'impostazione del valore su un valore inferiore a 100 è quasi sempre errato.

La ragione di ciò è che le applicazioni Linux allocano più del necessario. Supponiamo che allochino 8kb per memorizzare una stringa di testo di un paio di caratteri. Bene, ci sono diversi KB inutilizzati proprio lì. Le applicazioni lo fanno molto, ed è per questo che è progettato l'overcommit.

Quindi fondamentalmente con overcommit a 100, il kernel non consentirà alle applicazioni di allocare più memoria di quella che hai (swap + ram). Impostandolo a meno di 100 significa che non utilizzerai mai tutta la tua memoria. Se hai intenzione di configurare questa impostazione, dovresti impostarla su un valore superiore a 100 a causa dello scenario sopra menzionato, che è abbastanza comune.

Ora, per quanto riguarda il tuo problema con l'attivazione del killer OOM, l'impostazione manuale dell'overcommit probabilmente non risolverà questo problema. L'impostazione predefinita (determinazione euristica) è abbastanza intelligente.

Se desideri vedere se questa è davvero la causa del problema, guarda /proc/meminfo quando l'assassino OOM corre. Se vedi quel Committed_AS è vicino a CommitLimit , ma free mostra ancora la memoria libera disponibile, quindi sì, puoi regolare manualmente l'overcommit per il tuo scenario. L'impostazione di questo valore su un valore troppo basso farà sì che OOM killer inizi a uccidere le applicazioni quando hai ancora molta memoria libera. L'impostazione di un valore troppo alto può causare la morte di applicazioni casuali quando tentano di utilizzare la memoria a cui sono state allocate, ma non è effettivamente disponibile (quando tutta la memoria viene effettivamente esaurita).

Soluzione 2:

La sezione 9.6 "Overcommit e OOM" nel documento menzionato da @dunxd è particolarmente esplicita sui pericoli di consentire l'overcommit. Tuttavia, il 80 anche a me sembrava interessante, quindi ho condotto alcuni test.

Quello che ho scoperto è che il file overcommit_ratio influisce sulla RAM totale disponibile per TUTTI i processi. I processi root non sembrano essere trattati diversamente dai normali processi utente.

Impostando il rapporto su 100 o meno dovrebbe fornire la semantica classica dove restituiscono valori da malloc/sbrk sono affidabili. Impostandolo rapporti inferiori a 100 potrebbe essere un modo per riservare più RAM per attività non di processo come la memorizzazione nella cache e così via.

Quindi, sul mio computer con 24 GiB di RAM, con swap disabilitato, 9 GiB in uso, con top mostrando

Mem:  24683652k total,  9207532k used, 15476120k free,    19668k buffers
Swap:        0k total,        0k used,        0k free,   241804k cached

Ecco alcuni overcommit_ratio impostazioni e quanta RAM il mio programma ram-consumer potrebbe catturare (toccando ogni pagina) - in ogni caso il programma è terminato in modo pulito una volta malloc fallito.

 50    ~680 MiB
 60   ~2900 MiB
 70   ~5200 MiB
100  ~12000 MiB

L'esecuzione di più contemporaneamente, anche con alcuni come utente root, non ha modificato la quantità totale che hanno consumato insieme. È interessante notare che non è stato in grado di consumare gli ultimi 3+ GiB circa; il free non è sceso molto al di sotto di quanto mostrato qui:

Mem:  24683652k total, 20968212k used,  3715440k free,    20828k buffers

Gli esperimenti sono stati disordinati:tutto ciò che utilizza malloc al momento in cui tutta la RAM è in uso tende a bloccarsi, poiché molti programmatori sono terribili nel controllare gli errori di malloc in C, alcune librerie di raccolte popolari lo ignorano completamente e C ++ e vari altri linguaggi sono persino peggio.

La maggior parte delle prime implementazioni della RAM immaginaria che ho visto erano per gestire un caso molto specifico, in cui un singolo processo di grandi dimensioni - diciamo il 51% + della memoria disponibile - aveva bisogno di fork() per exec() qualche programma di supporto, di solito molto, molto più piccolo. I sistemi operativi con semantica copy-on-write consentirebbero fork() , ma a condizione che se il processo fork provasse effettivamente a modificare troppe pagine di memoria (ognuna delle quali dovrebbe quindi essere istanziata come una nuova pagina indipendente dall'enorme processo iniziale) finirebbe per essere ucciso. Il processo genitore era in pericolo solo se allocava più memoria e poteva gestire l'esaurimento, in alcuni casi semplicemente aspettando che qualche altro processo morisse, e poi continuando. Il processo figlio di solito si è appena sostituito con un programma (tipicamente più piccolo) tramite exec() ed era quindi libero dalla condizione.

Il concetto di overcommit di Linux è un approccio estremo per consentire sia il fork() oltre a consentire ai singoli processi di sovrassegnare in modo massiccio. Le morti causate da OOM-killer si verificano in modo asincrono, anche per i programmi che lo fanno gestire l'allocazione della memoria in modo responsabile. Personalmente odio l'intero sistema l'overcommit in generale e l'oom-killer in particolare:promuove un approccio diabolico alla gestione della memoria che infetta le librerie e attraverso di esse ogni app che le utilizza.

Suggerirei di impostare il rapporto su 100 e di avere anche una partizione di swap che generalmente finirebbe per essere utilizzata solo da processi enormi, che spesso utilizzano solo una piccola frazione della parte di se stessi che viene inserita nello swap, e quindi proteggere la stragrande maggioranza dei processi dalla cattiva funzionalità di OOM killer. Questo dovrebbe proteggere il tuo server web da morte casuale e se è stato scritto per gestire malloc responsabilmente, anche al sicuro dall'uccisione di se stesso (ma non scommettere su quest'ultimo).

Ciò significa che lo sto usando in /etc/sysctl.d/10-no-overcommit.conf

vm.overcommit_memory = 2
vm.overcommit_ratio = 100

Linux
  1. Come cancellare la cache di memoria in Linux

  2. Configurazione di Apache per gestire WebSocks

  3. Limite di memoria PHP

  4. Jenkins attivo (uscito)

  5. Memoria inattiva di Linux

Come cancellare la memoria di scambio in Linux

Configurazione di logrotate in Linux

Configurazione di un server web per l'utilizzo di HTTPS

Installazione e configurazione di Jenkins in Linux

Utilizzo della memoria dei comandi TOP

Impostazione del fuso orario in Linux