GNU/Linux >> Linux Esercitazione >  >> Linux

Linux inizierà a uccidere i miei processi senza chiedermi se la memoria si sta esaurendo?

Può.

Ci sono due diverse condizioni di memoria insufficiente che puoi incontrare in Linux. Quello che incontri dipende dal valore di sysctl vm.overcommit_memory (/proc/sys/vm/overcommit_memory )

Introduzione:
Il kernel può eseguire ciò che viene chiamato "overcommit della memoria". Questo è quando il kernel alloca ai programmi più memoria di quanta sia realmente presente nel sistema. Questo viene fatto nella speranza che i programmi non utilizzino effettivamente tutta la memoria allocata, poiché si tratta di un evento abbastanza comune.

overcommit_memory =2

Quando overcommit_memory è impostato su 2 , il kernel non esegue alcun overcommit. Invece quando a un programma viene allocata memoria, è garantito l'accesso per avere quella memoria. Se il sistema non ha abbastanza memoria libera per soddisfare una richiesta di allocazione, il kernel restituirà semplicemente un errore per la richiesta. Spetta al programma gestire con garbo la situazione. Se non controlla che l'allocazione sia andata a buon fine quando in realtà non è riuscita, l'applicazione incontrerà spesso un segfault.

Nel caso del segfault, dovresti trovare una riga come questa nell'output di dmesg :

[1962.987529] myapp[3303]: segfault at 0 ip 00400559 sp 5bc7b1b0 error 6 in myapp[400000+1000]

Il at 0 significa che l'applicazione ha tentato di accedere a un puntatore non inizializzato, che può essere il risultato di una chiamata di allocazione della memoria fallita (ma non è l'unico modo).

overcommit_memory =0 e 1

Quando overcommit_memory è impostato su 0 o 1 , l'overcommit è abilitato e i programmi possono allocare più memoria di quella realmente disponibile.

Tuttavia, quando un programma desidera utilizzare la memoria che gli è stata allocata, ma il kernel scopre di non avere memoria sufficiente per soddisfarlo, deve recuperare un po' di memoria. Prima tenta di eseguire varie attività di pulizia della memoria, come come svuotare le cache, ma se questo non è sufficiente terminerà un processo. Questa terminazione viene eseguita dall'OOM-Killer. L'OOM-Killer esamina il sistema per vedere quali programmi utilizzano quale memoria, da quanto tempo sono in esecuzione, chi li esegue e una serie di altri fattori per determinare quale viene ucciso.

Dopo che il processo è stato terminato, la memoria che stava utilizzando viene liberata e il programma che ha appena causato la condizione di memoria esaurita ora ha la memoria di cui ha bisogno.

Tuttavia, anche in questa modalità, le richieste di allocazione possono ancora essere negate ai programmi. Quando overcommit_memory è 0 , il kernel tenta di indovinare quando dovrebbe iniziare a rifiutare le richieste di allocazione. Quando è impostato su 1 , non sono sicuro di quale determinazione utilizzi per determinare quando deve rifiutare una richiesta, ma può rifiutare richieste molto grandi.

Puoi vedere se l'OOM-Killer è coinvolto osservando l'output di dmesg e trovare messaggi come:

[11686.043641] Out of memory: Kill process 2603 (flasherav) score 761 or sacrifice child
[11686.043647] Killed process 2603 (flasherav) total-vm:1498536kB, anon-rss:721784kB, file-rss:4228kB

La verità è che indipendentemente dal modo in cui lo guardi, sia che il tuo processo si sia interrotto a causa del gestore della memoria del sistema o per qualcos'altro, è fermo un insetto. Cosa è successo a tutti quei dati che stavi elaborando in memoria? Avrebbe dovuto essere salvato.

Mentre overcommit_memory= è il modo più generale di configurare la gestione di Linux OOM, è anche regolabile per processo come:

echo [-+][n] >/proc/$pid/oom_adj

Usando -17 in quanto sopra escluderà un processo dalla gestione della memoria insufficiente. Probabilmente non è una grande idea in generale, ma se sei alla ricerca di bug potrebbe valerne la pena, specialmente se desideri sapere se era OOM o il tuo codice. Incrementare positivamente il numero renderà più probabile che il processo venga interrotto in un evento OOM, il che potrebbe consentirti di rafforzare meglio la resilienza del tuo codice in situazioni di memoria insufficiente e assicurarti di uscire con garbo quando necessario.

Puoi controllare le impostazioni correnti del gestore OOM per processo come:

cat /proc/$pid/oom_score 

Altrimenti potresti suicidarti:

sysctl vm.panic_on_oom=1
sysctl kernel.panic=X

Ciò imposterà il riavvio del computer in caso di condizione di memoria insufficiente. Tu imposti il ​​X sopra al numero di secondi in cui si desidera che il computer si arresti dopo un kernel panic prima del riavvio. Scatenati.

E se, per qualche motivo, decidi che ti piace, rendilo persistente:

echo "vm.panic_on_oom=1" >> /etc/sysctl.conf
echo "kernel.panic=X" >> /etc/sysctl.conf

Linux
  1. Linux:il sistema si blocca quando esaurisce la memoria?

  2. Linux:cosa succede quando esegui la sincronizzazione senza un percorso di destinazione??

  3. Emulatore Android Arresto anomalo del dispositivo all'avvio in Android Studio (Linux)

  4. In che modo l'errore di memoria a bit singolo influirà su Linux?

  5. Su Linux, da quando inizia a contare il tempo di attività?

Comprensione dei processi su Linux

Linux Oom in modo casuale quando c'è ancora memoria libera?

Come trovare i migliori processi in esecuzione in base all'utilizzo di memoria e CPU in Linux

Processi Linux:layout di memoria, uscita e funzioni C _exit

Memoria inattiva di Linux

Come diagnosticare le cause dei processi di uccisione di oom-killer