Pregunta

Tengo un problema en una máquina de prueba que ejecuta Red Hat Linux (la versión del kernel es 2.4.21-37.ELsmp) usando Java 1.6 (1.6.0_02 o 1.6.0_04).El problema es que, una vez que se crea una cierta cantidad de subprocesos en un solo grupo de subprocesos, el sistema operativo no quiere o no puede crear más.

Esto parece ser específico de la creación de subprocesos en Java, ya que el programa de límite de subprocesos de C pudo crear aproximadamente 1,5k subprocesos.Además, esto no sucede con una JVM Java 1.4...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 corta es de apenas 29 hilos.Esto se puede comprobar con un programa Java simple que simplemente crea subprocesos hasta que recibe un error y luego imprime la cantidad 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 utilizados 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 cual es de esperar, considerando que el problema parece estar relacionado con la creación de subprocesos del sistema operativo nativo).

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 de procesos de usuario no parece ser el problema.La búsqueda de información sobre lo que podría estar mal no ha dado muchos resultados, pero esta publicación parece indicar que al menos algunos núcleos de Red Hat limitan un proceso a 300 MB de memoria asignada para la pila, y a 10 MB por subproceso para la pila, parece que el problema podría estar ahí (aunque también parece extraño e improbable).

Intenté cambiar el tamaño de la pila con "ulimit -s" para probar esto, pero cualquier valor que no sea 10240 y la JVM no comienza con un error de:

Error occurred during initialization of VM
Cannot create VM thread. Out of system resources.

Generalmente puedo manejar Linux, pero realmente no sé mucho sobre la configuración del sistema y no he podido encontrar nada que aborde específicamente este tipo de situación.Se agradecería cualquier idea sobre qué sistema o configuración de JVM podría estar causando esto.

Ediciones:Ejecutando el programa de límite de subprocesos mencionado por pedestal, no hubo ningún error hasta que intentó crear el hilo 1529.

El problema tampoco ocurrió al usar una JVM 1.4 (ocurre con las JVM 1.6.0_02 y 1.6.0_04, 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 ejecuta esto con una JVM 1.4, se bloqueará cuando no pueda crear más subprocesos y requiera un kill -9 (al menos así fue para mí).

Más edición:

Resulta que el sistema que tiene el problema usa el modelo de subprocesos LinuxThreads, mientras que otro sistema que funciona bien usa el modelo NPTL.

¿Fue útil?

Solución 2

La actualización del kernel a una versión más nueva (2.6.algo) con subprocesos NPTL solucionó este problema.

Otros consejos

¿Has mirado este recurso?Indica que debería poder ejecutar thread-limit para encontrar el número máximo de subprocesos y modificarlo compilando glibc.

Esto es con Ubuntu Linux (1 GB de RAM)

dsm@localhost:~$ javac ThreadTest.java 
dsm@localhost:~$ java ThreadTest 
8113
dsm@localhost:~$ java -version
java version "1.6.0_07"
Java(TM) SE Runtime Environment (build 1.6.0_07-b06)
Java HotSpot(TM) Client VM (build 10.0-b23, mixed mode, sharing)
dsm@localhost:~$ 

¿Puedes probarlo con JRockit JVM?IIRC, tenía un modelo de subprocesos diferente al de Sun JVM original.

Los ajustes en /etc/security/limits.d/90-nproc.conf puede estar anulando su /etc/security/limits.conf ajustes.Eso puede hacer que el sistema actúe de una manera diferente a la que se muestra en ulimit -u.

https://bugzilla.redhat.com/show_bug.cgi?id=823030

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top