2010-01-24 5 views
21

Y a-t-il un moyen de faire fonctionner le tueur OOM et d'empêcher Linux de geler? J'ai couru des applications de Java et de C#, où n'importe quelle mémoire allouée est habituellement utilisée, et (si je les comprends bien) les overcommits font geler la machine. En ce moment, comme une solution temporaire, j'ai ajouté,Quelle est la meilleure façon d'empêcher le stockage hors mémoire (OOM) sur Linux?

vm.overcommit_memory = 2 
vm.overcommit_ratio = 10 

à /etc/sysctl.conf. Bravo à tous ceux qui peuvent expliquer pourquoi le tueur de MOO existant ne peut pas fonctionner correctement d'une manière garantie, tuant des processus chaque fois que le noyau manque de mémoire "réelle". Beaucoup de réponses vont dans le sens de Michael "si vous rencontrez des problèmes liés à OOM Killer, alors vous avez probablement besoin de réparer ce qui vous cause de manquer de mémoire". Je ne pense pas que ce soit la bonne solution. Il y aura toujours des applications avec des bugs, et j'aimerais ajuster le noyau pour que mon système ne gèle pas. Compte tenu de mes connaissances techniques actuelles, cela ne semble pas être impossible.

+0

Pour limiter la mémoire, pourquoi ne pas limiter la surcharges à la parité? – wallyk

+1

Le tueur OOM sur mes systèmes Linux semble fonctionner comme prévu. À quel point êtes-vous certain que vous êtes confronté à une défaillance du tueur OOM? Pourquoi pensez-vous que c'est la cause? Avez-vous aussi envisagé la possibilité de problèmes d'éboueurs? – dmckee

+0

@dmckee - toutes les autres applications se bloquent. @wallyk - qu'est-ce qui "limite la surenchère à la parité"? – gatoatigrado

Répondre

1

Si le paramètre oom_adj de votre processus est défini sur -17, il ne sera pas pris en compte pour la destruction. Je doute que ce soit le problème ici.

cat /proc/<pid>/oom_adj

vous dira la valeur de votre processus (es) de faire oom_adj.

+0

si 'cat/proc//oom_adj' ne fonctionne pas, utilisez' cat/proc//oom_score_adj' – erm3nda

0

Je dois dire que la meilleure façon d'éviter les blocages du MOO est de ne pas manquer de mémoire virtuelle. Si vous manquez régulièrement de mémoire virtuelle, ou si vous vous en approchez, vous avez de plus gros problèmes.

La plupart des tâches ne gèrent pas très bien les allocations de mémoire défaillantes, elles ont donc tendance à planter ou à perdre des données. L'exécution de la mémoire virtuelle (avec ou sans overcommit) entraînera l'échec de certaines allocations. C'est généralement mauvais. De plus, avant que votre système d'exploitation ne manque de mémoire virtuelle, il commencera à faire de mauvaises choses comme jeter des pages de bibliothèques partagées couramment utilisées, ce qui est susceptible de rendre les performances difficiles car elles doivent être retirées souvent, ce qui est très mauvais pour le débit.

Mes suggestions:

  • plus de RAM
  • Run moins de processus
  • Faire les processus que vous ne lancez utilisent moins de mémoire (ce qui peut inclure la fixation dans les fuites de mémoire)

Et éventuellement aussi

  • Se t plus d'espace d'échange

Si cela vous aide dans votre cas d'utilisation.

La plupart des serveurs multiprocessus exécutent un nombre configurable (maximum) de processus, de sorte que vous pouvez généralement le régler vers le bas. Les serveurs multithread vous permettent généralement de configurer la quantité de mémoire à utiliser pour leurs tampons, etc. en interne.

+1

J'ai fait une erreur: j'ai essayé d'afficher un fichier XML de 55 GByte. Après quelques dizaines de secondes, la machine a gelé. Je soupçonne qu'une partie du problème est que mon fichier d'échange n'a pas une taille de 55 Go. Cependant, il est mauvais de laisser une application d'espace utilisateur paralyser un système entier.À mon humble avis, si un seul processus utilise trop de RAM virtuelle, alors le noyau devrait tuer ** ce ** processus, libérant ainsi la RAM virtuelle, et permettant au reste du système de continuer. Il ne devrait pas être possible pour une application utilisateur d'amener le système à entrer dans un état où le seul recours est de redémarrer. – user1928764

4

Voici un script perl vraiment basique que j'ai écrit. Avec un peu de peaufinage, cela pourrait être utile.Vous avez juste besoin de changer les chemins que j'ai vers les chemins de tous les processus qui utilisent Java ou C#. Vous pouvez également modifier les commandes kill que j'ai utilisées pour redémarrer les commandes. Bien sûr, pour éviter de taper manuellement dans perl memusage.pl, vous pouvez le mettre dans votre fichier crontab pour qu'il s'exécute automatiquement. Vous pouvez également utiliser perl memusage.pl> log.txt pour enregistrer sa sortie dans un fichier journal. Désolé si cela n'aide pas vraiment, mais je m'ennuyais en buvant une tasse de café. :-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

Pas mal, mais peut-être pas si fiable. Peut-être que les ulimits durs fonctionneraient? Je n'arrive pas à les avoir quand même ... – gatoatigrado

+1

Désolé, mais qu'est-ce que tu voulais faire avec les ulimits durs? Gardez à l'esprit que vous ne pouvez définir que des limites strictes en tant que root. Il y a une configuration supplémentaire dans /etc/security/limits.conf, je crois. – user198470

1

Tout d'abord, comment pouvez-vous être sûr que les gels sont liés à OOM killer? J'ai un réseau de systèmes sur le terrain et je ne reçois pas des gels peu fréquents, qui ne semblent pas être liés à MOO (notre application est assez stable dans l'utilisation de la mémoire). Serait-ce autre chose? Y a-t-il du matériel intéressant? Des pilotes instables? Vidéo haute performance?

Même si le tueur du MOO est impliqué et a fonctionné, vous auriez encore des problèmes, parce que les choses que vous pensiez courir étaient maintenant mortes, et qui sait quel genre de désordre il laisse derrière lui. Vraiment, si vous rencontrez des problèmes liés à OOM Killer, alors vous avez probablement besoin de réparer ce qui vous cause de manquer de mémoire.

+0

une ou deux fois, j'ai été capable de tirer le moniteur du système avant que tout se fige. – gatoatigrado

0

J'ai constaté que les problèmes de stabilité de fixation repose principalement sur l'identification précise de la cause profonde. Malheureusement, cela nécessite d'être capable de voir ce qui se passe lorsque le problème se produit, ce qui est vraiment un mauvais moment pour essayer de lancer divers programmes de surveillance. Une chose que j'ai parfois trouvée utile était de lancer un petit script de surveillance au démarrage, qui enregistrait divers nombres intéressants et un instantané des processus en cours. Ensuite, en cas d'accident, je pouvais regarder la situation juste avant le crash. J'ai parfois trouvé que l'intuition était tout à fait fausse quant à la cause profonde. Malheureusement, ce script est depuis longtemps obsolète, ou je donnerais un lien.

Questions connexes