Un estado «Killed» sin informe de caída, sin traza y sin ningún aviso es de las cosas más desconcertantes que puede ver el dueño de un servidor, porque a diferencia de casi cualquier otro fallo, este no es culpa del software del juego, y el software del juego nunca llega a tener oportunidad de decir nada al respecto.
Por qué el cierre es instantáneo y silencioso
El límite de memoria de un contenedor lo aplica el núcleo del sistema operativo, no Java. Cuando el uso total de memoria —el heap de Java, más todo lo que Java asigna fuera del heap, más cualquier otro proceso dentro del contenedor— cruza ese límite, el núcleo no pregunta con educación. Manda una señal que termina el proceso al instante, sin que Java tenga oportunidad de registrar una excepción, escribir un informe de caída o siquiera volcar su propia salida. Un momento el servidor está corriendo; al siguiente, el proceso ya no existe.
Por esto la memoria de intercambio está desactivada por diseño y no por descuido: dejarla activa permitiría que un servidor que supera su límite de memoria se arrastrara en vez de morir, cambiando un fallo rápido y limpio por uno lento y degradado que suele ser peor para todos los jugadores conectados en ese momento, y lo haría a costa del rendimiento de E/S de NVMe sobre el que está construida el resto de la plataforma.
Qué usa memoria de verdad, más allá de -Xmx
| Consumidor | ¿Cuenta contra el límite del contenedor? |
|---|---|
El heap de Java, hasta -Xmx | Sí — es lo que controla ese flag |
| Pilas de hilos (una por hilo de plugin, por gestor de conexión) | Sí, y no está incluido en -Xmx |
| Búferes directos/fuera de heap (muy usados por Netty para redes) | Sí, y no está incluido en -Xmx |
| Archivos de región mapeados en memoria | Sí, aunque el núcleo los puede liberar con más facilidad bajo presión |
| Cualquier otro proceso del contenedor | Sí — un plugin de mapa web, un proxy incluido, cualquier otra cosa corriendo al lado |
-Xmx puesto demasiado cerca del límite del contenedorPoner -Xmx a toda la asignación de memoria no está usando los 4 GB con seguridad: está garantizando un cierre por OOM en cuanto las pilas de hilos y los búferes de red necesiten su parte, cosa que pasa con carga normal, no con carga rara. Dejar entre un 10 y un 20% de la memoria del plan sin asignar a -Xmx es lo que de verdad usa el plan con seguridad.
Diagnosticar de qué tipo de OOM se trata
- Comprueba si pasa en un momento predecible o va empeorando durante la sesión
Una fuga sube de forma constante a lo largo de la sesión y acaba matando el proceso pase lo que pase de margen. Un problema de margen mata más o menos al mismo nivel de memoria cada vez, a menudo ligado al pico de jugadores.
- Mira la gráfica de memoria durante una sesión entera, no solo en la caída
Una subida constante que nunca baja entre ratos tranquilos es la firma de una fuga, normalmente un plugin que guarda referencias a entidades, jugadores o chunks que debería soltar.
- Si es margen, baja
-Xmxprimero, no subas el planUna caída por
-Xmxpuesto demasiado alto es un problema de configuración que una mejora de plan da la casualidad de que tapa en vez de arreglar, y merece descartarse antes de gastar en más memoria que la misma mala configuración también acabaría llenando.
El servidor aguanta una sesión concurrida entera —el punto donde antes moría— con la memoria asentándose en el diente de sierra normal de la recolección de basura en vez de subir hasta el techo.