2010-01-24 19 views
21

¿Hay alguna manera de hacer que OOM Killer funcione y evitar que se congele Linux? He estado ejecutando aplicaciones Java y C#, donde normalmente se utiliza cualquier memoria asignada, y (si las entiendo bien) los sobrecompromisos hacen que la máquina se congele. En este momento, como una solución temporal, agregué,¿Cuál es la mejor forma de evitar la falta de memoria (OOM) en Linux?

vm.overcommit_memory = 2 
vm.overcommit_ratio = 10 

a /etc/sysctl.conf.

Felicita a cualquiera que pueda explicar por qué el asesino OOM existente no puede funcionar correctamente de forma garantizada, matando procesos cada vez que el kernel se quede sin memoria "real".

EDIT - muchas respuestas son similares a las de Michael: "si experimentas problemas relacionados con OOM killer, entonces probablemente necesites arreglar lo que esté causando que te quedes sin memoria". No creo que esta sea la solución correcta. Siempre habrá aplicaciones con errores, y me gustaría ajustar el kernel para que todo mi sistema no se congele. Dado mi entendimiento técnico actual, esto no parece que debería ser imposible.

+0

Para limitar la memoria, ¿por qué no limitaría el exceso de compromiso a la paridad? – wallyk

+1

El asesino OOM en mis sistemas Linux parece funcionar como está diseñado. ¿Qué tan seguro está de que está experimentando una falla OOM killer? ¿Por qué crees que esa es la causa? ¿Has considerado la posibilidad de un problema con el recolector de basura también? – dmckee

+0

@dmckee - todas las demás aplicaciones se congelan. @wallyk - ¿Qué es "limitar el exceso de compromiso con la paridad"? – gatoatigrado

Respuesta

1

Si el oom_adj de sus procesos está configurado en -17, no se considerará para matar aunque dudo que sea el problema aquí.

cat /proc/<pid>/oom_adj

le dirá el valor de su proceso (s) 's oom_adj.

+0

si 'cat/proc//oom_adj' no funciona, use' cat/proc//oom_score_adj' – erm3nda

0

Tendría que decir que la mejor manera de evitar las congelaciones de OOM es no quedarse sin memoria virtual. Si regularmente te estás quedando sin memoria virtual o acercándote, entonces tienes problemas más grandes.

La mayoría de las tareas no manejan muy bien las asignaciones de memoria fallidas, por lo que tienden a fallar o perder datos. Si se queda sin memoria virtual (con o sin compromiso excesivo), algunas asignaciones fallarán. Esto usualmente es malo.

Además, antes de que su sistema operativo se quede sin memoria virtual, empezará a hacer cosas malas como descartar páginas de bibliotecas compartidas de uso común, lo que probablemente hará que el rendimiento sea negativo, ya que tienen que volver a instalarse con frecuencia. malo para el rendimiento.

Mis sugerencias:

  • más RAM
  • Run menos procesos
  • Hacer que los procesos que se ejecutan usar menos memoria (esto puede incluir la fijación de las pérdidas de memoria en ellos)

Y posiblemente también

  • Se t up more swap space

Si esto es útil en su caso de uso.

La mayoría de los servidores multiproceso ejecutan un número configurable (máximo) de procesos, por lo que normalmente puede ajustarlo hacia abajo. Los servidores de subprocesos múltiples generalmente le permiten configurar la cantidad de memoria que usará para sus búfers, etc. internamente.

+1

Cometí un error: intenté ver un archivo XML de 55 GByte. Después de algunas decenas de segundos, la máquina se congeló. Sospecho que parte del problema es que mi archivo de intercambio no tiene 55 GB de tamaño. Sin embargo, es un mal diseño dejar que una aplicación de espacio de usuario paralice todo un sistema.En mi humilde opinión, si un solo proceso está usando demasiada RAM virtual, entonces el kernel debería matar ** ese ** proceso, liberando así la RAM virtual y permitiendo que el resto del sistema continúe. No debe ser posible que una aplicación de usuario haga que el sistema entre en un estado en el que el único recurso sea reiniciar. – user1928764

4

A continuación se muestra un script de perl realmente básico que escribí. Con un poco de ajuste podría ser útil.Solo necesita cambiar las rutas que tengo a las rutas de cualquier proceso que use Java o C#. Podrías cambiar los comandos kill que he usado para reiniciar comandos también. Por supuesto, para evitar escribir en perl memusage.pl manualmente, puede ponerlo en su archivo crontab para que se ejecute automáticamente. También puede usar perl memusage.pl> log.txt para guardar su salida en un archivo de registro. Lo siento si realmente no ayuda, pero estaba aburrido mientras tomaba una taza 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

No está mal, pero tal vez no tan confiable. ¿Tal vez los ulimits duros funcionarían? Parece que no puedo conseguirlos ... – gatoatigrado

+1

Disculpa, pero ¿qué querías hacer con los ulimits duros? Tenga en cuenta que solo puede establecer límites estrictos como root. Hay una configuración adicional en /etc/security/limits.conf, creo. – user198470

1

En primer lugar, ¿cómo se puede estar seguro de que las heladas están relacionadas con OOM killer? Tengo una red de sistemas en el campo y no recibo congelamientos infrecuentes, que no parecen estar relacionados con OOM (nuestra aplicación es bastante estable en uso de memoria). ¿Podría ser otra cosa? ¿Hay algún hardware interesante involucrado? Cualquier controlador inestable? ¿Video de alto rendimiento?

Incluso si el asesino de OOM está involucrado, y funcionó, todavía tendrías problemas, porque las cosas que pensabas que se estaban ejecutando ahora están muertas, y quién sabe qué tipo de desastre queda.

Realmente, si tiene problemas relacionados con OOM killer, entonces probablemente necesite arreglar lo que le esté causando que se quede sin memoria.

+0

una o dos veces, he podido levantar el monitor del sistema antes de que todo se congele. – gatoatigrado

0

He encontrado que solucionar los problemas de estabilidad se basa principalmente en la identificación precisa de la causa raíz. Desafortunadamente, esto requiere poder ver lo que sucede cuando ocurre el problema, que es un momento realmente malo para tratar de iniciar varios programas de monitoreo.

Una cosa que a veces me pareció útil fue iniciar un pequeño script de supervisión en el momento del arranque, que registraría varios números interesantes e instantáneas de los procesos en ejecución. Entonces, en caso de un accidente, podría ver la situación justo antes del accidente. A veces descubrí que la intuición era bastante incorrecta sobre la causa raíz. Desafortunadamente, ese guión ya no está actualizado, o le daría un enlace.

Cuestiones relacionadas