Hmm, non sono del tutto convinto dagli argomenti a favore del sovraccarico e dell'assassino di OOM ... Quando il womble scrive,
"Il killer OOM provoca il caos solo se hai sovraccaricato il tuo sistema. Dagli abbastanza scambio e non eseguire applicazioni che improvvisamente decidono di consumare enormi quantità di RAM, e non avrai problemi."
Si tratta di descrivere uno scenario ambientale in cui overcommit e OOM killer non vengono applicati o non "agiscono" realmente (se tutte le applicazioni allocassero la memoria in base alle necessità e ci fosse memoria virtuale sufficiente da allocare, le scritture di memoria seguiranno da vicino le allocazioni di memoria senza errori, quindi non potremmo davvero parlare di un sistema ipercompresso anche se fosse abilitata una strategia di sovraccarico). Si tratta di un'ammissione implicita che il sovraccarico e il killer OOM funzionano meglio quando non è necessario il loro intervento, che è in qualche modo condiviso dalla maggior parte dei sostenitori di questa strategia, per quanto ne so (e ammetto che non posso dire molto ...). Inoltre, facendo riferimento ad applicazioni con comportamenti specifici durante la preallocazione della memoria, mi viene da pensare che una gestione specifica possa essere regolata a livello di distribuzione, anziché avere un valore predefinito,
Per quanto riguarda la JVM, beh, è una macchina virtuale, in una certa misura ha bisogno di allocare tutte le risorse di cui ha bisogno all'avvio, in modo da poter creare il suo ambiente "falso" per le sue applicazioni e mantenere la sua risorsa disponibile separata dall'host ambiente, per quanto possibile. Pertanto, potrebbe essere preferibile che fallisca all'avvio, invece che dopo un po 'come conseguenza di una condizione OOM "esterna" (causata da overcommit / OOM killer / qualunque cosa), o comunque soffrire per tale condizione che interferisce con la propria strategie interne di gestione OOM (in generale, una VM dovrebbe ottenere tutte le risorse necessarie dall'inizio e il sistema host dovrebbe "ignorarle" fino alla fine, allo stesso modo in cui qualsiasi quantità di RAM fisica condivisa con una scheda grafica non è mai - e non può essere - toccato dal sistema operativo).
A proposito di Apache, dubito che avere l'intero server occasionalmente ucciso e riavviato sia meglio che lasciare che un singolo figlio, insieme a una singola connessione, fallisca dal suo inizio (= il bambino / la connessione) (come se fosse un'istanza completamente nuova di la JVM creata dopo un'altra istanza eseguita per un po '). Immagino che la migliore 'soluzione' potrebbe dipendere da un contesto specifico. Ad esempio, considerando un servizio di e-commerce, potrebbe essere di gran lunga preferibile avere, a volte, alcune connessioni al carrello della spesa che falliscono casualmente invece di perdere l'intero servizio, con il rischio, ad esempio, di interrompere una finalizzazione dell'ordine in corso, oppure (forse peggio) un processo di pagamento, con tutte le conseguenze del caso (forse innocuo, ma forse dannoso - e di sicuro, in caso di problemi,
Allo stesso modo, su una workstation il processo che consuma la maggior parte delle risorse, e quindi la coda per essere una prima scelta per il killer OOM, potrebbe essere un'applicazione ad alta intensità di memoria, come un transcoder video o un software di rendering, probabilmente l'unica applicazione l'utente vuole non essere toccato. Queste considerazioni mi suggeriscono che la politica di default del killer OOM è troppo aggressiva. Utilizza un approccio "peggio adattamento" che è in qualche modo simile a quello di alcuni filesystem (l'OOMK prova e libera quanta più memoria possibile, riducendo il numero di sottoprocessi uccisi, al fine di prevenire qualsiasi ulteriore intervento in breve tempo, come inoltre un fs può allocare più spazio su disco rispetto a quello effettivamente necessario per un determinato file, per evitare ulteriori allocazioni se il file cresce e quindi prevenire la frammentazione, in una certa misura).
Tuttavia, penso che una politica opposta, come un approccio "best fit", potrebbe essere preferibile, in modo da liberare la memoria esatta necessaria ad un certo punto e non preoccuparsi di processi "grandi", che potrebbero essere sprecati memoria, ma potrebbe anche non esserlo, e il kernel non può saperlo (hmm, posso immaginare che tenere traccia del conteggio degli accessi alle pagine e del tempo potrebbe suggerire se un processo sta allocando memoria non ha più bisogno, quindi per indovinare se un processo sta sprecando memoria o semplicemente usando molto, ma i ritardi di accesso dovrebbero essere ponderati sui cicli della CPU per distinguere uno spreco di memoria da un'applicazione intensiva di memoria e CPU, ma, sebbene potenzialmente inaccurato, tale euristica potrebbe avere un sovraccarico eccessivo).
Inoltre, potrebbe non essere vero che uccidere il minor numero possibile di processi sia sempre una buona scelta. Ad esempio, in un ambiente desktop (pensiamo a un nettop o un netbook con risorse limitate, per esempio) un utente potrebbe eseguire un browser con diverse schede (quindi, consumando memoria - supponiamo che questa sia la prima scelta per OOMK) , oltre ad alcune altre applicazioni (un elaboratore di testi con dati non salvati, un client di posta, un lettore di pdf, un lettore multimediale, ...), oltre a qualche demone (di sistema), oltre ad alcune istanze di file manager. Ora, si verifica un errore OOM e OOMK sceglie di uccidere il browser mentre l'utente sta facendo qualcosa di ritenuto "importante" sulla rete ... l'utente sarebbe deluso. D'altra parte, chiudendo i pochi file manager "
Ad ogni modo, penso che l'utente dovrebbe essere abilitato a prendere una decisione da solo su cosa fare. In un sistema desktop (= interattivo), che dovrebbe essere relativamente abbastanza facile da fare, a condizione che siano riservate risorse sufficienti per chiedere all'utente di chiudere qualsiasi applicazione (ma anche chiudere alcune schede potrebbe essere sufficiente) e gestire la sua scelta (un'opzione potrebbe consiste nella creazione di un file di scambio aggiuntivo, se lo spazio è sufficiente). Per i servizi (e in generale), prenderei in considerazione anche altri due possibili miglioramenti: uno sta registrando gli intervalli killer OOM, nonché i processi che avviano / eseguono il fork degli errori in modo tale che l'errore possa essere facilmente debug (ad esempio, un'API potrebbe informare il processo che emette la creazione del nuovo processo o il biforcazione - quindi un server come Apache, con una patch adeguata, potrebbe fornire una registrazione migliore per alcuni errori); ciò potrebbe essere fatto in modo indipendente dal sovraccarico / OOMK in corso; in secondo luogo, ma non per importanza, potrebbe essere istituito un meccanismo per mettere a punto l'algoritmo OOMK - so che è possibile, in una certa misura, definire una politica specifica su un processo per processo, ma mirerei a meccanismo di configurazione "centralizzato", basato su uno o più elenchi di nomi di applicazioni (o ID) per identificare i processi pertinenti e dare loro un certo grado di importanza (secondo gli attributi elencati); tale meccanismo dovrebbe (o almeno potrebbe) essere anche stratificato, in modo tale che ci possa essere un elenco definito dall'utente di livello superiore, un elenco definito dal sistema (distribuzione) e voci definite dall'applicazione (livello inferiore) (quindi , ad esempio, un gestore di file DE potrebbe incaricare OOMK di eliminare in modo sicuro qualsiasi istanza,
Inoltre, potrebbe essere fornita un'API per consentire alle applicazioni di aumentare o ridurre il loro livello di 'importanza' in fase di esecuzione (rispetto agli scopi di gestione della memoria e indipendentemente dalla priorità di esecuzione), in modo che, ad esempio, un elaboratore di testi possa iniziare con una "importanza" bassa, ma aumentala man mano che alcuni dati vengono conservati prima di scaricare in un file o viene eseguita un'operazione di scrittura e riduci nuovamente l'importanza una volta terminata tale operazione (analogamente, un gestore di file potrebbe cambiare livello quando è passato da legare i file alla gestione dei dati e viceversa, invece di utilizzare processi separati, e Apache potrebbe dare diversi livelli di importanza ai diversi figli, o cambiare uno stato figlio secondo una politica decisa da amministratori di sistema ed esposta attraverso Apache - o qualsiasi altro tipo di server - impostazioni). Ovviamente, una simile API potrebbe e sarebbe abusata / abusata, ma penso che sia una preoccupazione minore rispetto al fatto che il kernel uccida arbitrariamente i processi per liberare memoria senza alcuna informazione rilevante su ciò che sta accadendo sul sistema (e il consumo di memoria / il tempo di creazione o lo stesso sono "abbastanza pertinente o" convalidante "per me) - solo gli utenti, gli amministratori e gli autori di programmi possono davvero determinare se un processo è" ancora necessario "per qualche motivo, qual è il motivo e / o se l'applicazione si trova in uno stato leader alla perdita di dati o altri danni / problemi se uccisi; tuttavia, si potrebbe ancora ipotizzare, ad esempio la ricerca di risorse di un certo tipo (descrittori di file, socket di rete, ecc.) acquisite da un processo e con operazioni in sospeso potrebbero dire se un processo dovrebbe trovarsi in uno stato "superiore" rispetto a quello impostato,
Oppure, evita semplicemente il commit eccessivo e lascia che il kernel faccia esattamente ciò che deve fare un kernel, allocando risorse (ma non salvandole arbitrariamente come fa il killer OOM), pianificando processi, prevenendo fame e deadlock (o salvando da esse), assicurando la piena anticipazione e separazione degli spazi di memoria e così via ...
Spenderei anche qualche parola in più sugli approcci di overcommit. Da altre discussioni ho avuto l'idea che una delle principali preoccupazioni sul sovraccarico (sia come motivo per volerlo sia come fonte di possibili problemi) consiste nella gestione delle forcelle: onestamente, non so esattamente come la copia- la strategia di scrittura è implementata, ma penso che qualsiasi politica aggressiva (o ottimistica) potrebbe essere mitigata da una strategia di localizzazione simile allo scambio. Cioè, invece di limitarsi a clonare (e ad adattare) una code page di processo biforcuta e strutture di pianificazione, alcune altre pagine di dati potrebbero essere copiate prima di una scrittura effettiva, scegliendo tra quelle pagine a cui il processo parent ha avuto accesso per scrivere più frequentemente (ovvero, utilizzando un contatore per le operazioni di scrittura).
Tutto, ovviamente, IMHO.