Gestisci le condizioni di memoria insufficiente?


Risposte:


4

Eviterei l'OOM come evitare un incidente.

Evita di fare un grosso pezzo di lavoro (e alloca un grosso pezzo di memoria) contemporaneamente. Conservare i dati sul disco, fidarsi della cache del disco del sistema operativo e utilizzare il più possibile l'IO mappato in memoria e operare solo su una piccola parte di dati alla volta. Se è necessario disporre di grandi quantità di dati online (forniti con bassa latenza), tenerli nella memoria su più macchine, come fanno tutte le grandi società di motori di ricerca. O acquista un SSD.


Apparentemente questo ha più senso.
mbq,

2
C'è stato un grande dibattito su come gestire OOM con garbo (RAII, sicurezza delle eccezioni, blah ...) ma una volta mi sono reso conto che in un sistema multithread con più moduli dinamici (alcuni di terze parti), anche se il tuo thread non ha funzionato crash, c'è un momento di sfortunato momento in cui ogni thread vedrà un OOM. Se anche uno solo decidesse di andare avanti, non puoi fare altro che testimone oculare.
rwong

13

La maggior parte delle persone che rispondono a questa domanda probabilmente non hanno mai lavorato su sistemi embedded, dove malloc restituendo 0 è una possibilità molto reale. Su un sistema su cui sto attualmente lavorando, ci sono un totale di 4,25 KB di RAM (ovvero 4352 byte). Sto allocando 64 byte per lo stack e attualmente ho un heap di 1600 byte. Proprio ieri stavo eseguendo il debug di una routine di heap walk in modo da poter seguire l'allocazione e la liberazione della memoria. L'heap walk utilizza un piccolo buffer (30 byte) allocato staticamente per l'output su una porta seriale. Verrà disattivato per la versione di rilascio.

Poiché si tratta di un prodotto di consumo, è meglio che non rimanga a corto di memoria una volta che il prodotto è stato rilasciato. Sono sicuro che lo farà durante lo sviluppo. In ogni caso, tutto ciò che posso fare è emettere un segnale acustico l'altoparlante un paio di volte e forzare un riavvio.


2
Montare le funzionalità all'interno di un piccolo spazio è sorprendente ... è una forma d'arte come il bonsai
rwong

6
Molti progetti su sistemi embedded semplicemente vietano l'allocazione dinamica della memoria. L'unico caso di OOM rimane lo stack overflow.
mouviciel,

Hai ragione, ma soprattutto con la tua prima frase: la maggior parte di questo semplicemente non è rilevante per la maggior parte degli sviluppatori per fortuna.
Konrad Rudolph,

4

Ad essere onesti, in tutti i progetti che ho fatto (tieni presente che non sto ancora lavorando da nessuna parte), non ho mai pensato che potesse accadere, e quindi suppongo che i miei programmi morirebbero molto rapidamente.

Inoltre, la gestione di una OOM richiede di aver preallocato le risorse per visualizzare il messaggio di errore o per salvare tutto, il che può essere un po 'scomodo.

Sento che in questi giorni, la memoria costa meno delle arachidi, non è qualcosa che dovrebbe accadere frequentemente. All'alba della memoria protetta e prima, forse era una preoccupazione, ma ora? Gli unici errori OOM che io abbia mai visto provengono dal codice errato.


Posso pensare di recuperare parte della memoria che il processo ha già e provare a sopravvivere e recuperare (difficile se hai scaricato qualcosa di utile) o sopravvivere come dati + resti che provano a salvarlo.
mbq,

2

Il controllo dei codici di ritorno malloc è comunque inutile.

I moderni sistemi operativi sovraccaricano la memoria: forniscono ai processi più memoria di quella attualmente disponibile. La memoria concessa al processo è virtuale, tutta mappata su una singola pagina azzerata.

È solo quando si scrive in memoria che una pagina fisica, unica, viene allocata per i processi. Se questa allocazione fallisce, il kernel termina un processo (forse il tuo!) Nel tentativo di trovare memoria. A quel punto non c'è più nulla da fare.


Ho avuto l'idea di entrare in un ciclo while con un lungo sonno all'interno - e possibilmente di recuperare se il processo sarebbe sopravvissuto all'assassino di OOM. Ho l'impressione che i processi siano stati piuttosto interrotti a causa del suo tentativo di utilizzare l'indirizzo 0, ma non ho fatto alcun test solido.
mbq,

Non devi fare nulla di speciale per affrontare il killer OOM. Se il processo lo ha attivato ma non è stato selezionato, non lo saprà mai. Tutto funzionerà come se ci fosse abbastanza memoria. Se invece il processo è selezionato, verrà terminato e non è possibile fare nulla al riguardo.
Kristof Provost,

Ma posso provare ad attendere OOM per liberare un po 'di memoria e quindi provare a allocare nuovamente e continuare. Ho l'impressione che malloc / new non stia aspettando che ciò accada.
mbq,

No, non puoi. La tua allocazione avrà sempre successo. Otterrai tutta la memoria virtuale che desideri. Solo quando lo tocchi viene allocata la memoria fisica. Non appena si tocca una pagina non allocata, il processo viene sospeso. Il kernel cercherà più memoria, il che potrebbe portarlo a terminare un processo per avere più memoria. Se ciò ha esito positivo (e non uccide il tuo!), La pagina verrà allocata e il processo riprenderà. Non c'è modo per il tuo processo di dire che questo è successo.
Kristof Provost,

2
Sono abbastanza sicuro che Windows non si sovraccarica mai. Può impegnare più della RAM, ma non più della RAM + file di scambio.
CodesInChaos

2

A meno che non si stia sviluppando per sistemi embedded, sistemi in tempo reale o sistemi che sono così critici che i guasti possono costare vite o miliardi di dollari ... Quindi probabilmente non vale la pena finanziariamente preoccuparsi delle condizioni di memoria insufficiente.

Nella maggior parte dei casi, c'è ancora poco da fare quando si è esauriti la memoria, poiché non c'è memoria per creare nuovi oggetti o eseguire attività che potrebbero fare qualcosa. Devi valutare il costo dell'app per la gestione di OOM rispetto al vantaggio che ottieni dal farlo.


I sistemi in tempo reale non hanno bisogno di controllare di più su un guasto malloc rispetto agli altri sistemi.
zneak,

@zneak - Untrue. I sistemi in tempo reale devono essere prevedibili e la memoria insufficiente non è prevedibile a meno che non lo si stia pianificando specificamente.
Erik Funkenbusch,

Quindi cos'altro farai una volta colpito l'OOM?
zneak,

Memoria libera, annullamento di processi, ecc. Un sistema in tempo reale in genere non ha memoria virtuale o sistema di scambio perché deve essere deterministico. Quindi, può esaurire la memoria molto più facilmente.
Erik Funkenbusch,

Dato un certo percorso di codice che porterà inevitabilmente a un errore OOM, non vedo come l'arresto anomalo sia un approccio meno deterministico rispetto alla liberazione della memoria e all'annullamento dei processi.
zneak,

1

Vorrei sempre verificare la presenza di errori. Se qualcosa restituisce una condizione di errore, deve essere gestita dal programma. Anche se è un messaggio che dice "Memoria insufficiente, devo andare!", È meglio di "Violazione dell'accesso", "core dumped" o qualsiasi altra cosa. Una è una condizione di errore che gestisci, l'altra è un bug. E l'utente lo percepirà anche come tale.

Per il tuo caso specifico, potresti provare a ripristinare l'operazione, liberando le risorse che hai allocato fino a raggiungere il punto di errore, riportando l'errore e proseguendo l'esecuzione (forse quando stai provando a chiudere l'applicazione, puoi dare il opzione per uscire immediatamente). In questo modo, l'utente può decidere cosa fare o provare a liberare un po 'di memoria armeggiando, chiudendo file, ecc. Naturalmente, il modo in cui è possibile gestire la situazione dipende fortemente dal programma, un programma che non dovrebbe essere interattivo probabilmente deve solo registrare l'errore e uscire o continuare.

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.