¿Cuál es la mejor manera de evitar la falta de memoria(OOM) se congela en Linux?
memory linux-kernel (5)
¿Hay alguna manera de hacer que el asesino de OOM 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é,
vm.overcommit_memory = 2
vm.overcommit_ratio = 10
a /etc/sysctl.conf.
Felicitaciones 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".
EDITAR - 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.
Si el oom_adj de su proceso está configurado a -17, no se considerará para matar aunque dudo que sea el problema aquí.
cat /proc/<pid>/oom_adj
le dirá el valor del oom_adj de su (s) proceso (s).
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 malo, ya que tienen que retirarse a menudo, lo que es muy perjudicial para el rendimiento.
Mis sugerencias:
- Consigue más ram
- Ejecuta menos procesos
- Haga que los procesos que ejecuta usen menos memoria (Esto puede incluir la fijación de pérdidas de memoria en ellos)
Y posiblemente también
- Configurar más espacio de intercambio
Si eso 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.
Debajo hay 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();
En primer lugar, ¿cómo puedes 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 estás experimentando problemas relacionados con OOM killer, entonces probablemente necesites arreglar lo que esté causando que te quedes sin memoria.
Descubrí que solucionar problemas de estabilidad depende principalmente de identificar con precisión 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 encontré útil fue comenzar un pequeño script de monitoreo 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.