Límite de subprocesos de proceso único bajo de Java en Red Hat Linux
Estoy experimentando un problema en una máquina de prueba que ejecuta Red Hat Linux (la versión del kernel es 2.4.21-37.ELsmp) utilizando Java 1.6 (1.6.0_02 o 1.6.0_04). El problema es que una vez que se crea un cierto número de subprocesos en un solo grupo de subprocesos, el sistema operativo no está dispuesto o no puede crear más.
Esto parece ser específico para Java creando subprocesos, ya que el programa de límite de subprocesos C pudo crear aproximadamente 1.5k subprocesos. Además, esto no ocurre con una Java 1.4 JVM ... puede crear más de 1.4k subprocesos, aunque obviamente se manejan de manera diferente con respecto al sistema operativo.
En este caso, la cantidad de hilos que se está cortando es de apenas 29 hilos. Esto se puede probar con un programa Java simple que solo crea subprocesos hasta que recibe un error y luego imprime el número de subprocesos que creó. El error es un
java.lang.OutOfMemoryError: unable to create new native thread
Esto parece no verse afectado por cosas como la cantidad de subprocesos en uso por otros procesos o usuarios o la cantidad total de memoria que el sistema está utilizando en ese momento. Las configuraciones de JVM como Xms, Xmx y Xss tampoco parecen cambiar nada (lo que se espera, considerando que el problema parece ser con la creación de subprocesos nativos del sistema operativo).
La salida de "ulimit -a" es la siguiente:
core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes, -l) 4 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 7168 virtual memory (kbytes, -v) unlimited
El límite del proceso del usuario no parece ser el problema. La búsqueda de información sobre lo que podría estar mal no ha resultado mucho, peroesta publicación parece indicar que al menos algunos kernels de Red Hat limitan un proceso a 300 MB de memoria asignada para la pila, y a 10 MB por hilo por pila, parece que el problema podría estar allí (aunque parece extraño y poco probable también).
He intentado cambiar el tamaño de pila con "ulimit -s" para probar esto, pero cualquier valor que no sea 10240 y la JVM no se inicia con un error de:
Error occurred during initialization of VM Cannot create VM thread. Out of system resources.
En general, puedo moverme por Linux, pero realmente no sé mucho acerca de la configuración del sistema, y no he podido encontrar nada específicamente que aborde este tipo de situación. Cualquier idea sobre qué sistema o configuración de JVM podría estar causando esto sería apreciada.
Ediciones: Ejecutando el programa de límite de hilos mencionado porzócalo, no hubo falla hasta que trató de crear el hilo 1529.
El problema tampoco ocurrió con una JVM 1.4 (ocurre con 1.6.0_02 y 1.6.0_04 JVM, no se puede probar con una JVM 1.5 en este momento).
El código para la prueba de hilo que estoy usando es el siguiente:
public class ThreadTest {
public static void main(String[] pArgs) throws Exception {
try {
// keep spawning new threads forever
while (true) {
new TestThread().start();
}
}
// when out of memory error is reached, print out the number of
// successful threads spawned and exit
catch ( OutOfMemoryError e ) {
System.out.println(TestThread.CREATE_COUNT);
System.exit(-1);
}
}
static class TestThread extends Thread {
private static int CREATE_COUNT = 0;
public TestThread() {
CREATE_COUNT++;
}
// make the thread wait for eternity after being spawned
public void run() {
try {
sleep(Integer.MAX_VALUE);
}
// even if there is an interruption, dont do anything
catch (InterruptedException e) {
}
}
}
}
Si ejecutas esto con un JVM 1.4, se bloqueará cuando no pueda crear más subprocesos y requerirá un kill -9 (al menos lo hizo para mí).
Más Editar:
Resulta que el sistema que tiene el problema está utilizando el modelo de subprocesamiento LinuxThreads, mientras que otro sistema que funciona bien está utilizando el modelo NPTL.