2010-01-24 10 views
21

C'è un modo per far funzionare il killer OOM e impedire il congelamento di Linux? Ho eseguito applicazioni Java e C#, dove di solito viene utilizzata qualsiasi memoria allocata e (se le capisco bene) i overcommits stanno causando il blocco della macchina. Proprio ora, come soluzione temporanea, ho aggiunto,Qual è il modo migliore per evitare il blocco della memoria insufficiente (OOM) su Linux?

vm.overcommit_memory = 2 
vm.overcommit_ratio = 10 

a /etc/sysctl.conf.

Complimenti a tutti coloro che possono spiegare perché l'assassino OOM esistente non può funzionare correttamente in modo garantito, uccidendo i processi ogni volta che il kernel esaurisce la memoria "reale".

EDIT - molte risposte sono sulla falsariga di quelle di Michael "se si verificano problemi relativi a OOM killer, allora probabilmente è necessario correggere qualsiasi cosa causi l'esaurimento della memoria". Non penso che questa sia la soluzione corretta. Ci saranno sempre app con bug e mi piacerebbe regolare il kernel in modo che il mio intero sistema non si blocchi. Date le mie attuali conoscenze tecniche, questo non sembra debba essere impossibile.

+0

Per limitare la memoria, perché non limitare l'overcommit alla parità? – wallyk

+1

Il killer di OOM sui miei sistemi Linux sembra funzionare come progettato. Sei sicuro che stai vivendo un guasto a OOM killer? Perché pensi che sia la causa? Hai considerato anche la possibilità di problemi con i raccoglitori? – dmckee

+0

@dmckee - tutte le altre applicazioni si bloccano. @wallyk: cosa "limita l'overcommit alla parità"? – gatoatigrado

risposta

1

Se il tuo oom_adj dei processi è impostato su -17, non verrà considerato per l'uccisione, anche se dubito che sia il problema qui.

cat /proc/<pid>/oom_adj

vi dirà il valore del processo (es) 's oom_adj.

+0

se 'cat/proc//oom_adj' non funziona, usare' cat/proc//oom_score_adj' – erm3nda

0

Direi che il modo migliore per evitare che OOM si blocchi è di non esaurire la memoria virtuale. Se stai esaurendo regolarmente la memoria virtuale o ti stai avvicinando, allora hai problemi più grandi.

La maggior parte delle attività non gestisce le allocazioni di memoria non riuscite in modo ottimale, quindi tende a bloccarsi o a perdere dati. L'esaurimento della memoria virtuale (con o senza overcommit) causerà il fallimento di alcune assegnazioni. Questo di solito è cattivo.

Inoltre, prima che il tuo sistema operativo esaurisca la memoria virtuale, inizierà a fare cose cattive come scartare le pagine dalle librerie condivise di uso comune, il che probabilmente farà risucchiare le prestazioni in quanto devono essere richiamate spesso, il che è molto cattivo per il throughput.

I miei suggerimenti:

  • Ottenga ram
  • Run minor numero di processi
  • rendere i processi si corre utilizzare meno memoria (che prevede anche fissare le perdite di memoria in loro)

E forse anche

  • Se t up più spazio di scambio

Se questo è utile nel tuo caso d'uso.

La maggior parte dei server multi-processo esegue un numero configurabile (massimo) di processi, pertanto è possibile regolarlo tipicamente verso il basso. I server multithread in genere consentono di configurare la quantità di memoria da utilizzare per i buffer ecc. Internamente.

+1

Ho fatto un errore: ho provato a visualizzare un file XML da 55 GByte. Dopo alcune decine di secondi, la macchina si bloccò. Sospetto che parte del problema sia che il mio file di scambio non ha una dimensione di 55 GByte. Tuttavia, è un cattivo progetto lasciare che un'applicazione dello spazio utente paralizzi un intero sistema.IMHO, se un singolo processo utilizza troppa RAM virtuale, allora il kernel dovrebbe uccidere ** quel ** processo, liberando così la RAM virtuale e permettendo al resto del sistema di continuare. Non dovrebbe essere possibile per un'applicazione utente far sì che il sistema entri in uno stato in cui l'unica risorsa è il riavvio. – user1928764

4

Di seguito è riportato uno script perl molto semplice che ho scritto. Con un po 'di ritocco potrebbe essere utile.Hai solo bisogno di cambiare i percorsi che ho per i percorsi di tutti i processi che usano Java o C#. È possibile modificare anche i comandi kill utilizzati per riavviare i comandi. Ovviamente per evitare di digitare perl memusage.pl manualmente, puoi inserirlo nel tuo file crontab per essere eseguito automaticamente. È anche possibile utilizzare perl memusage.pl> log.txt per salvare l'output in un file di registro. Scusa se non aiuta davvero, ma ero annoiato mentre bevevo una tazza di caffè. :-D Cheers

#!/usr/bin/perl -w 
# Checks available memory usage and calculates size in MB 
# If free memory is below your minimum level specified, then 
# the script will attempt to close the troublesome processes down 
# that you specify. If it can't, it will issue a -9 KILL signal. 
# 
# Uses external commands (cat and pidof) 
# 
# Cheers, insertable 

our $memmin = 50; 
our @procs = qw(/usr/bin/firefox /usr/local/sbin/apache2); 

sub killProcs 
{ 
    use vars qw(@procs); 
    my @pids =(); 
    foreach $proc (@procs) 
    { 
     my $filename=substr($proc, rindex($proc,"/")+1,length($proc)-rindex($proc,"/")-1); 
     my $pid = `pidof $filename`; 
     chop($pid); 
     my @pid = split(/ /,$pid); 
     push @pids, $pid[0]; 
    } 
    foreach $pid (@pids) 
    { 
     #try to kill process normall first 
     system("kill -15 " . $pid); 
     print "Killing " . $pid . "\n"; 
     sleep 1; 
     if (-e "/proc/$pid") 
     { 
      print $pid . " is still alive! Issuing a -9 KILL...\n"; 
      system("kill -9 " + $pid); 
      print "Done.\n"; 
     } else { 
      print "Looks like " . $pid . " is dead\n"; 
     } 
    } 
    print "Successfully finished destroying memory-hogging processes!\n"; 
    exit(0); 
} 

sub checkMem 
{ 
    use vars qw($memmin); 
    my ($free) = $_[0]; 
    if ($free > $memmin) 
    { 
     print "Memory usage is OK\n"; 
     exit(0); 
    } else { 
     killProcs(); 
    } 
} 

sub main 
{ 
    my $meminfo = `cat /proc/meminfo`; 
    chop($meminfo); 
    my @meminfo = split(/\n/,$meminfo); 
    foreach my $line (@meminfo) 
    { 
     if ($line =~ /^MemFree:\s+(.+)\skB$/) 
     { 
      my $free = ($1/1024); 
      &checkMem($free); 
     } 
    } 
} 

main(); 
+0

Non male, ma forse non così affidabile. Forse i duri ulimits avrebbero funzionato? Non riesco a convincerli a farlo ... – gatoatigrado

+1

Scusa, ma cosa volevi fare con i duri ulimits? Tieni presente che puoi impostare solo limiti rigidi come root. C'è una configurazione extra in /etc/security/limits.conf, credo. – user198470

1

Prima di tutto, come si può essere sicuri che i blocchi siano correlati a OOM killer? Ho una rete di sistemi sul campo e ho problemi di congelamento non frequenti, che non sembrano essere correlati a OOM (la nostra app è abbastanza stabile nell'uso della memoria). Potrebbe essere qualcos'altro? C'è qualche hardware interessante coinvolto? Qualsiasi driver instabile? Video ad alte prestazioni?

Anche se l'OOM killer è coinvolto e ha funzionato, avresti ancora problemi, perché le cose che pensavi fossero in esecuzione ora sono morte, e chissà che tipo di pasticcio è rimasto indietro.

In realtà, se si verificano problemi relativi a OOM killer, è probabile che sia necessario correggere qualsiasi problema che causa l'esaurimento della memoria.

+0

una o due volte, sono riuscito a sollevare il monitor di sistema prima che tutto si blocchi. – gatoatigrado

0

Ho trovato che risolvere i problemi di stabilità si basa principalmente sull'identificazione accurata della causa principale. Sfortunatamente, ciò richiede di essere in grado di vedere cosa succede quando si verifica il problema, il che è davvero un brutto momento per provare ad avviare vari programmi di monitoraggio.

Una cosa che a volte ho trovato utile era avviare un piccolo script di monitoraggio all'avvio che registrava vari numeri interessanti e creava un'istantanea dei processi in esecuzione. Poi, in caso di incidente, ho potuto vedere la situazione appena prima dell'incidente. A volte ho trovato che l'intuizione era piuttosto sbagliata riguardo alla causa principale. Sfortunatamente, questo script è obsoleto, o darei un link.

Problemi correlati