¿Cómo consigo que el asesino de OOM de Linux no mate mis procesos cuando la memoria física es baja pero hay mucho espacio de intercambio?
He deshabilitado el asesinato de OOM y sobrecompromiso con sysctl vm.overcommit_memory = 2.
La VM tiene 3 GB de intercambio no fragmentado absolutamente gratuito y los procesos que se están eliminando OOM tienen un uso máximo de memoria inferior a 200 MB.
Sé que el intercambio a largo plazo será horrible para el rendimiento, pero necesito usar el intercambio en este momento para hacer pruebas funcionales bajo valgrind donde los requisitos de memoria son mucho mayores.
Mar 7 02:43:11 myhost kernel: memcheck-amd64- invoked oom-killer: gfp_mask=0x24002c2, order=0, oom_score_adj=0
Mar 7 02:43:11 myhost kernel: memcheck-amd64- cpuset=/ mems_allowed=0
Mar 7 02:43:11 myhost kernel: CPU: 0 PID: 3841 Comm: memcheck-amd64- Not tainted 4.4.0-x86_64-linode63 #2
Mar 7 02:43:11 myhost kernel: Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
Mar 7 02:43:11 myhost kernel: 0000000000000000 0000000000000000 ffffffff8158cbcc ffff880032d7bc18
Mar 7 02:43:11 myhost kernel: ffffffff811c6a55 00000015118e701d ffffffff81044a8d 00000000000003e2
Mar 7 02:43:11 myhost kernel: ffffffff8110f5a1 0000000000000000 00000000000003e2 ffffffff81cf15cc
Mar 7 02:43:11 myhost kernel: Call Trace:
Mar 7 02:43:11 myhost kernel: [<ffffffff8158cbcc>] ? dump_stack+0x40/0x50
Mar 7 02:43:11 myhost kernel: [<ffffffff811c6a55>] ? dump_header+0x59/0x1dd
Mar 7 02:43:11 myhost kernel: [<ffffffff81044a8d>] ? kvm_clock_read+0x1b/0x1d
Mar 7 02:43:11 myhost kernel: [<ffffffff8110f5a1>] ? __raw_callee_save___pv_queued_spin_unlock+0x11/0x1e
Mar 7 02:43:11 myhost kernel: [<ffffffff81183316>] ? oom_kill_process+0xc0/0x34f
Mar 7 02:43:11 myhost kernel: [<ffffffff811839b2>] ? out_of_memory+0x3bf/0x406
Mar 7 02:43:11 myhost kernel: [<ffffffff81187bbd>] ? __alloc_pages_nodemask+0x8ba/0x9d8
Mar 7 02:43:11 myhost kernel: [<ffffffff811b82e8>] ? alloc_pages_current+0xbc/0xe0
Mar 7 02:43:11 myhost kernel: [<ffffffff811b096c>] ? __vmalloc_node_range+0x12d/0x20a
Mar 7 02:43:11 myhost kernel: [<ffffffff811e0e62>] ? alloc_fdtable+0x6a/0xd8
Mar 7 02:43:11 myhost kernel: [<ffffffff811b0a83>] ? __vmalloc_node+0x3a/0x3f
Mar 7 02:43:11 myhost kernel: [<ffffffff811e0e62>] ? alloc_fdtable+0x6a/0xd8
Mar 7 02:43:11 myhost kernel: [<ffffffff811b0ab0>] ? vmalloc+0x28/0x2a
Mar 7 02:43:11 myhost kernel: [<ffffffff811e0e62>] ? alloc_fdtable+0x6a/0xd8
Mar 7 02:43:11 myhost kernel: [<ffffffff811e1338>] ? dup_fd+0x103/0x1f0
Mar 7 02:43:11 myhost kernel: [<ffffffff810dd143>] ? copy_process+0x5aa/0x160d
Mar 7 02:43:11 myhost kernel: [<ffffffff8110f5a1>] ? __raw_callee_save___pv_queued_spin_unlock+0x11/0x1e
Mar 7 02:43:11 myhost kernel: [<ffffffff810de2fc>] ? _do_fork+0x7d/0x291
Mar 7 02:43:11 myhost kernel: [<ffffffff810ea186>] ? __set_current_blocked+0x47/0x52
Mar 7 02:43:11 myhost kernel: [<ffffffff810ea1f2>] ? sigprocmask+0x61/0x6a
Mar 7 02:43:11 myhost kernel: [<ffffffff81998eae>] ? entry_SYSCALL_64_fastpath+0x12/0x71
Mar 7 02:43:11 myhost kernel: Mem-Info:
Mar 7 02:43:11 myhost kernel: active_anon:15 inactive_anon:18 isolated_anon:0
Mar 7 02:43:11 myhost kernel: active_file:7 inactive_file:8 isolated_file:0
Mar 7 02:43:11 myhost kernel: unevictable:0 dirty:3 writeback:26 unstable:0
Mar 7 02:43:11 myhost kernel: slab_reclaimable:1798 slab_unreclaimable:3674
Mar 7 02:43:11 myhost kernel: mapped:8 shmem:1 pagetables:752 bounce:0
Mar 7 02:43:11 myhost kernel: free:1973 free_pcp:0 free_cma:0
Mar 7 02:43:11 myhost kernel: Node 0 DMA free:3944kB min:60kB low:72kB high:88kB active_anon:0kB inactive_anon:0kB active_file:28kB inactive_file:32kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:15992kB managed:15908kB
mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:72kB slab_unreclaimable:236kB kernel_stack:48kB pagetables:60kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:36
0 all_unreclaimable? yes
Mar 7 02:43:11 myhost kernel: lowmem_reserve[]: 0 972 972 972
Mar 7 02:43:11 myhost kernel: Node 0 DMA32 free:3948kB min:3956kB low:4944kB high:5932kB active_anon:60kB inactive_anon:72kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:1032064kB manag
ed:999552kB mlocked:0kB dirty:12kB writeback:104kB mapped:32kB shmem:4kB slab_reclaimable:7120kB slab_unreclaimable:14460kB kernel_stack:2112kB pagetables:2948kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_t
mp:0kB pages_scanned:792 all_unreclaimable? yes
Mar 7 02:43:11 myhost kernel: lowmem_reserve[]: 0 0 0 0
Mar 7 02:43:11 myhost kernel: Node 0 DMA: 20*4kB (UM) 17*8kB (UM) 13*16kB (M) 14*32kB (UM) 8*64kB (UM) 4*128kB (M) 4*256kB (M) 0*512kB 1*1024kB (M) 0*2048kB 0*4096kB = 3944kB
Mar 7 02:43:11 myhost kernel: Node 0 DMA32: 934*4kB (UM) 28*8kB (UM) 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 3960kB
Mar 7 02:43:11 myhost kernel: 71 total pagecache pages
Mar 7 02:43:11 myhost kernel: 42 pages in swap cache
Mar 7 02:43:11 myhost kernel: Swap cache stats: add 245190, delete 245148, find 77026/136093
Mar 7 02:43:11 myhost kernel: Free swap = 3118172kB
Mar 7 02:43:11 myhost kernel: Total swap = 3334140kB
Mar 7 02:43:11 myhost kernel: 262014 pages RAM
Mar 7 02:43:11 myhost kernel: 0 pages HighMem/MovableOnly
Mar 7 02:43:11 myhost kernel: 8149 pages reserved
Mar 7 02:43:11 myhost kernel: [ pid ] uid tgid total_vm rss nr_ptes nr_pmds swapents oom_score_adj name
Mar 7 02:43:11 myhost kernel: [ 2054] 0 2054 5101 1 15 4 283 0 upstart-udev-br
Mar 7 02:43:11 myhost kernel: [ 2063] 0 2063 12362 1 28 4 184 -1000 systemd-udevd
Mar 7 02:43:11 myhost kernel: [ 3342] 102 3342 9780 1 23 3 89 0 dbus-daemon
Mar 7 02:43:11 myhost kernel: [ 3423] 0 3423 10864 1 26 3 85 0 systemd-logind
Mar 7 02:43:11 myhost kernel: [ 3441] 0 3441 15344 0 34 3 184 -1000 sshd
Mar 7 02:43:11 myhost kernel: [ 3450] 0 3450 4786 0 14 3 43 0 atd
Mar 7 02:43:11 myhost kernel: [ 3451] 0 3451 5915 0 17 4 65 0 cron
Mar 7 02:43:11 myhost kernel: [ 3457] 101 3457 63962 0 28 3 202 0 rsyslogd
Mar 7 02:43:11 myhost kernel: [ 3516] 0 3516 3919 1 13 3 156 0 upstart-file-br
Mar 7 02:43:11 myhost kernel: [ 3518] 0 3518 4014 0 13 3 265 0 upstart-socket-
Mar 7 02:43:11 myhost kernel: [ 3557] 0 3557 66396 0 32 3 1802 0 fail2ban-server
Mar 7 02:43:11 myhost kernel: [ 3600] 0 3600 3956 1 13 3 39 0 getty
Mar 7 02:43:11 myhost kernel: [ 3601] 0 3601 3198 1 12 3 37 0 getty
Mar 7 02:43:11 myhost kernel: [ 3673] 0 3673 26411 1 55 3 252 0 sshd
Mar 7 02:43:11 myhost kernel: [ 3740] 1000 3740 26411 1 52 3 253 0 sshd
Mar 7 02:43:11 myhost kernel: [ 3741] 1000 3741 5561 0 16 3 431 0 bash
Mar 7 02:43:11 myhost kernel: [ 3820] 103 3820 7863 1 21 3 152 0 ntpd
Mar 7 02:43:11 myhost kernel: [ 3837] 1000 3837 31990 0 58 4 12664 0 memcheck-amd64-
Mar 7 02:43:11 myhost kernel: [ 3841] 1000 3841 32006 0 59 4 12812 0 memcheck-amd64-
Mar 7 02:43:11 myhost kernel: [ 3844] 1000 3844 31950 0 57 4 12035 0 memcheck-amd64-
Mar 7 02:43:11 myhost kernel: [ 3849] 1000 3849 31902 0 56 4 11482 0 memcheck-amd64-
Mar 7 02:43:11 myhost kernel: [ 3853] 1000 3853 1087 0 7 3 27 0 lsof
Mar 7 02:43:11 myhost kernel: [ 3854] 0 3854 26140 5 55 3 230 0 sshd
Mar 7 02:43:11 myhost kernel: [ 3855] 104 3855 15699 0 33 3 202 0 sshd
Mar 7 02:43:11 myhost kernel: Out of memory: Kill process 3841 (memcheck-amd64-) score 11 or sacrifice child
Mar 7 02:43:11 myhost kernel: Killed process 3841 (memcheck-amd64-) total-vm:128024kB, anon-rss:0kB, file-rss:0kB
Esto es / proc / meminfo
MemTotal: 1015460 kB
MemFree: 277508 kB
MemAvailable: 322032 kB
Buffers: 8336 kB
Cached: 42208 kB
SwapCached: 46088 kB
Active: 58844 kB
Inactive: 116100 kB
Active(anon): 34784 kB
Inactive(anon): 89620 kB
Active(file): 24060 kB
Inactive(file): 26480 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 3334140 kB
SwapFree: 3215756 kB
Dirty: 16 kB
Writeback: 0 kB
AnonPages: 121128 kB
Mapped: 15072 kB
Shmem: 4 kB
Slab: 22668 kB
SReclaimable: 8028 kB
SUnreclaim: 14640 kB
KernelStack: 2016 kB
PageTables: 2532 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 3841868 kB
Committed_AS: 380460 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 0 kB
VmallocChunk: 0 kB
DirectMap4k: 14208 kB
DirectMap2M: 1034240 kB
DirectMap1G: 0 kB
all_unreclaimable
sí). Estas son páginas bloqueadas en la RAM, generalmente porque están ancladas o en uso por el núcleo. Nada de lo que le quedaba en RAM era intercambiable en ese momento; todo lo que podría haberse cambiado ya lo había sido. Nuevamente, la solución es más RAM.Respuestas:
Esto parece ser un problema en combinación de dos factores:
Esta es en parte una de las líneas que describe por qué sucede esto:
La otra línea es esta:
| La primera línea es la máscara GFP asignada para la asignación. Básicamente describe lo que el kernel está permitido / no permitido hacer para satisfacer esta solicitud. La máscara indica un grupo de banderas estándar. El último bit, '2', sin embargo, indica que la asignación de memoria debe provenir de la
HighMem
zona.Si observa de cerca la salida de OOM, verá que
HighMem/Normal
realmente no existe ninguna zona.HighMem
(generalmente también llamadoNormal
x86_64) tiende a mapear la memoria para zonas fuera de los rangos estándar de 896MiB directamente accesibles al núcleo en sistemas de 32 bits. En x86_64HighMem/Normal
parece cubrir todas las páginas con un tamaño superior a 3GiB.DMA32
contiene una zona utilizada para la memoria que sería accesible en dispositivos DMA de 32 bits, es decir, puede abordarlos con punteros de 4 bytes. Creo queDMA
es para dispositivos DMA de 16 bits.En términos generales, en sistemas con poca memoria
Normal
no existiría, dado que yaDMA32
cubre todas las direcciones virtuales disponibles.La razón por la que OOM mata es porque hay una asignación de memoria para una
HighMem
zona con 0 páginas disponibles. Dado que el manejador sin memoria no tiene absolutamente ninguna manera de satisfacerlo, esta zona tiene páginas para usar intercambiando, eliminando otros procesos o cualquier otro truco, OOM-killer simplemente lo mata.Creo que esto es causado por la máquina virtual del host que se infla al arrancar. En los sistemas KVM, hay dos valores que puede establecer.
La forma en que esto funciona es que puede agregar memoria en caliente a su servidor hasta la memoria disponible. Sin embargo, su sistema recibe la memoria actual.
Cuando se inicia una VM KVM, comienza con la asignación máxima de memoria posible (la memoria disponible). Gradualmente, durante la fase de arranque del sistema, KVM recupera esta memoria utilizando su globo, dejándolo en cambio con la configuración de memoria actual que tiene.
Es mi creencia lo que sucedió aquí. Linode le permite expandir la memoria, dándole mucho más al inicio del sistema.
Esto significa que hay una
Normal/HighMem
zona al comienzo de la vida útil del sistema. Cuando el hipervisor lo aleja, la zona normal desaparece correctamente del administrador de memoria. Pero, sospecho que la configuración de la bandera de si dicha zona está disponible para asignar no se borra cuando debería. Esto lleva al núcleo a intentar asignar desde una zona que no existe.En términos de resolver esto, tiene dos opciones.
Mencione esto en las listas de correo del núcleo para ver si esto realmente es un error, un comportamiento esperado o nada que ver con lo que estoy diciendo.
Solicite que linode configure la 'memoria disponible' en el sistema para que sea la misma asignación de 1GiB que la 'memoria actual'. Por lo tanto, el sistema nunca se infla y nunca obtiene una zona Normal en el arranque, manteniendo la bandera despejada. ¡Buena suerte para que hagan eso!
Debería poder probar que este es el caso configurando su propia VM en la configuración KVM disponible para 6GiB, actual a 1GiB y ejecutando su prueba usando el mismo núcleo para ver si ocurre este comportamiento que ve arriba. Si es así, cambie la configuración 'disponible' para igualar la corriente de 1GiB y repita la prueba.
Estoy haciendo un montón de conjeturas educadas aquí y leyendo entre líneas un poco para llegar a esta respuesta, pero lo que digo parece encajar con los hechos descritos anteriormente.
Sugiero probar mi hipótesis y hacernos saber a todos el resultado.
fuente
Para responder a su pregunta principal, use
oom_score_adj
(kernel> = 2.6.36) o para kernels anteriores (> = 2.6.11)oom_adj
, vea man procHay mucho más para leer, pero establecer oom_score_adj en -1000 o oom_adj en -17 logrará lo que desea.
El problema es que algo más será asesinado. Tal vez sería mejor determinar por qué se invoca a OOM y lidiar con eso.
fuente
Varios pensamientos (de mis comentarios anteriores), y enlaces a lecturas interesantes sobre su situación:
Le recomiendo que compruebe que 1) puede direccionar más de 3Gb con su kernel y configuración actual (& cpu) [porque si 3Gb es un límite para su sistema y sistema operativo, lo está excediendo]. 2) que permite el intercambio y que el subsistema de intercambio está en su lugar y funcionando. buena suerte (no explicaré cómo, ya que depende de su configuración y detalles. Los motores de búsqueda ayudarán). Y que no está desbordando una tabla de kernel (¿nb de pids? O cualquier otra cosa (algunas pueden configurarse en tiempo de compilación del kernel).
Compruebe que todo (hardware, hardware simulado de vm, etc.) es de 64 bits. (ver por ejemplo: https://askubuntu.com/questions/313379/i-installed-a-64-bit-os-in-a-32-bit-processor/313381 ). El cpu y el sistema operativo host y el subsistema vm y el sistema operativo vm deben estar todos habilitados para 64 bits, de lo contrario no tendrá un vm real de 64 bits
Algunas buenas lecturas:
y finalmente: http://www.oracle.com/technetwork/articles/servers-storage-dev/oom-killer-1911807.html muestra una manera de evitar que su proceso sea el objetivo del asesino de Oom. (
echo -17 > /proc/PROCESSPID/oom_adj
) Podría ser propenso a cambios, y podría ser algo malo (causar otro tipo de fallas ya que el sistema ahora no puede simplemente matar al delincuente principal ...) Úselo con precaución. @iain tenga en cuenta que "oom_adj" es para núcleos más antiguos, y debe ser reemplazado por "oom_score_adj" en los más nuevos. Gracias Iain)fuente
además de mencionar el
oom_score_adj
aumento para el proceso en cuestión (que probablemente no ayudará mucho, haría menos probable que ese proceso se matara PRIMERO, pero como eso es solo un sistema de proceso de memoria intensiva, probablemente no se recuperará hasta que finalmente esté asesinado), aquí hay algunas ideas para modificar:vm.overcommit_memory=2
, también ajustevm.overcommit_ratio
a quizás 90 (alternativamente, configurevm.overcommit_memory=0
- vea los documentos de sobrecompromiso del kernel )vm.min_free_kbytes
para mantener siempre algo de RAM física libre y, por lo tanto, reducir las posibilidades de que OOM necesite matar algo (pero no exagere, ya que lo hará instantáneamente).vm.swappiness
a 100 (para hacer que el kernel se intercambie más fácilmente )Tenga en cuenta que si tiene muy poca memoria para realizar la tarea en cuestión, incluso si no realiza OOM, puede (o no) volverse EXTREMADAMENTE lento: el trabajo de media hora (en un sistema con suficiente RAM) puede llevar fácilmente varias semanas ( cuando la RAM se reemplaza por intercambio) para completar en casos extremos, o incluso colgar VM completa. Ese es especialmente el caso si el intercambio se realiza en discos rotativos clásicos (a diferencia de los SSD) debido a lecturas / escrituras aleatorias masivas que son muy caras para ellos.
fuente
Intentaría habilitar el exceso de compromiso y ver si eso ayuda. Su proceso parece fallar dentro de una
fork
llamada, lo que requiere tanta memoria virtual como el proceso inicial.overcommit_memory=2
no hace que su proceso sea inmune al asesino de OOM, solo evita que su proceso lo active asignando demasiado. Otros procesos pueden producir errores de asignación no relacionados (por ejemplo, obtener un bloque de memoria contiguo), que aún activan el asesino OOM y eliminan el proceso.Alternativamente (y más al punto), como sugieren varios comentarios, compre más RAM.
fuente
Breve historia: pruebe una versión diferente del kernel. Tengo un sistema que mostró errores OOM con los núcleos 4.2.0-x y 4.4.0-x, pero no con 3.19.0-x.
Larga historia: (¡no demasiado larga!) Tengo un Compaq DC5000 todavía en servicio aquí, actualmente con 512 MB de RAM (y una parte de eso, como 32-128 MB, se le da al video a bordo ...) NFS, tengo un monitor conectado, así que ocasionalmente iniciaré sesión en él (Ubuntu Classic, no Unity).
A través de Ubuntu HWE estuve ejecutando el kernel 3.19.x por un buen tiempo; terminaría intercambiando como 200-300MB de cosas, pero aparentemente era algo no utilizado, no habría ninguna actividad de intercambio por tener que intercambiarlo más tarde por lo que podía ver.
Kernel 4.2.0-x y ahora kernel 4.4.0-x, puedo comenzar una escritura NFS gruesa, solo 220MB en el intercambio (es decir, 1.3GB gratis), y comenzará a OOM a matar cosas. No afirmaré si se trata de un error del kernel o un "problema de ajuste" (como una reserva de 64 MB que normalmente está bien, pero ¿demasiado alta en un sistema de ~ 400 MB o menos?)
Sin faltarle el respeto a aquellos que dicen que de alguna manera se está rompiendo solo porque espera usar swap; con el debido respeto te equivocas. No será rápido, pero solía usar 1 o 2 GB en el intercambio en algunos sistemas de 512 MB a 1 GB. Por supuesto, algunos tipos de software mlock son un montón de RAM, pero en mi caso (ya que estoy ejecutando el mismo software solo en un kernel diferente), claramente este no es el caso.
fuente