¿Cuántos hilos puede admitir una máquina virtual Java?

212

¿Cuántos hilos puede admitir una máquina virtual Java? ¿Esto varía según el proveedor? por sistema operativo? ¿otros factores?

McGovernTheory
fuente

Respuestas:

170

Esto depende de la CPU que esté utilizando, del sistema operativo, de lo que estén haciendo otros procesos, de la versión de Java que esté utilizando y de otros factores. He visto que un servidor de Windows tiene más de 6500 subprocesos antes de apagar la máquina. La mayoría de los hilos no estaban haciendo nada, por supuesto. Una vez que la máquina alcanzó alrededor de 6500 subprocesos (en Java), toda la máquina comenzó a tener problemas y se volvió inestable.

Mi experiencia muestra que Java (versiones recientes) puede consumir felizmente tantos subprocesos como la computadora puede alojar sin problemas.

Por supuesto, debe tener suficiente RAM y debe haber iniciado Java con suficiente memoria para hacer todo lo que los subprocesos están haciendo y tener una pila para cada subproceso. Cualquier máquina con una CPU moderna (las dos generaciones más recientes de AMD o Intel) y con 1 a 2 gigabytes de memoria (dependiendo del sistema operativo) puede admitir fácilmente una JVM con miles de subprocesos.

Si necesita una respuesta más específica que esta, su mejor opción es hacer un perfil.

Eddie
fuente
86

Um, mucho.

Hay varios parámetros aquí. La VM específica, además de que generalmente también hay parámetros de tiempo de ejecución en la VM. Eso es algo impulsado por el sistema operativo: ¿qué soporte tiene el sistema operativo subyacente para los subprocesos y qué limitaciones les impone? Si la máquina virtual realmente utiliza hilos de nivel de sistema operativo, el viejo y bueno hilo rojo / hilo verde.

Lo que significa "apoyo" es otra pregunta. Si escribes un programa Java que es algo así como

   class DieLikeADog {
         public static void main(String[] argv){
             for(;;){
                new Thread(new SomeRunaable).start();
             }
         }
    }

(y no me quejo de los pequeños detalles de sintaxis, estoy tomando mi primera taza de café), entonces seguramente debería esperar que se ejecuten cientos o miles de hilos. Pero crear un subproceso es relativamente costoso, y la sobrecarga del planificador puede ser intensa; no está claro que pueda hacer que esos hilos hagan algo útil.

Actualizar

Bien, no pude resistirme. Aquí está mi pequeño programa de prueba, con un par de adornos:

public class DieLikeADog {
    private static Object s = new Object();
    private static int count = 0;
    public static void main(String[] argv){
        for(;;){
            new Thread(new Runnable(){
                    public void run(){
                        synchronized(s){
                            count += 1;
                            System.err.println("New thread #"+count);
                        }
                        for(;;){
                            try {
                                Thread.sleep(1000);
                            } catch (Exception e){
                                System.err.println(e);
                            }
                        }
                    }
                }).start();
        }
    }
}

En OS / X 10.5.6 en Intel y Java 6 5 (ver comentarios), esto es lo que obtuve

Nuevo hilo # 2547
Nuevo hilo # 2548
Nuevo hilo # 2549
No se puede crear hilo: 5
Nuevo hilo # 2550
Excepción en el hilo "principal" java.lang.OutOfMemoryError: no se puede crear un nuevo hilo nativo
        en java.lang.Thread.start0 (Método nativo)
        en java.lang.Thread.start (Thread.java:592)
        en DieLikeADog.main (DieLikeADog.java:6)
Charlie Martin
fuente
10
¿Con cuánta memoria comenzó la JVM? Eso importa.
Eddie
10
Java 6, actualización 13, Ubuntu 8.10 de 32 bits, 4Gig ram, configuración predeterminada de JVM = 6318 subprocesos.
Steve K
99
Je, juega con el tamaño de la pila de hilos. java -Xss100k me permitió crear hilos 19702 en Linux.
Steve K
21
java -Xss50k me consiguió alrededor de 32k hilos. Sin embargo, eso maximizó mis 4 gigas de carnero. Tuve que detener algunos procesos en ejecución para recuperar suficiente memoria en mi máquina para bifurcar un nuevo proceso para matar a Java;) - buenos tiempos.
Steve K
21
Usando Java 7 en Windows 7, acabo de crear 200,000 hilos antes de que mi sistema muriera. El Administrador de tareas mostró el proceso con 8 GB de RAM. Sin embargo, no estoy seguro de por qué se detuvo allí ... Tengo 12 GB de RAM en mi computadora. Entonces esto puede estar llegando a algún otro límite.
Dobes Vandermeer
50

Después de leer la publicación de Charlie Martin, tenía curiosidad por saber si el tamaño del montón hace alguna diferencia en la cantidad de hilos que puede crear, y el resultado me dejó totalmente estupefacto.

Usando JDK 1.6.0_11 en Vista Home Premium SP1, ejecuté la aplicación de prueba de Charlie con diferentes tamaños de almacenamiento dinámico, entre 2 MB y 1024 MB.

Por ejemplo, para crear un montón de 2 MB, invocaría la JVM con los argumentos -Xms2m -Xmx2m.

Aquí están mis resultados:

2 mb --> 5744 threads
4 mb --> 5743 threads
8 mb --> 5735 threads
12 mb --> 5724 threads
16 mb --> 5712 threads
24 mb --> 5687 threads
32 mb --> 5662 threads
48 mb --> 5610 threads
64 mb --> 5561 threads
96 mb --> 5457 threads
128 mb --> 5357 threads
192 mb --> 5190 threads
256 mb --> 5014 threads
384 mb --> 4606 threads
512 mb --> 4202 threads
768 mb --> 3388 threads
1024 mb --> 2583 threads

Entonces, sí, el tamaño del montón definitivamente importa. Pero la relación entre el tamaño de almacenamiento dinámico y el recuento máximo de subprocesos es INVERSAMENTE proporcional.

Lo cual es raro.

benjismith
fuente
11
tendría sentido si CADA subproceso recibe un montón de ese tamaño.
Thorbjørn Ravn Andersen
1
Advertencia: mi máquina no tiene 2583 GB de RAM. O intercambiar. Y la JVM no asigna espacio de almacenamiento dinámico local de subprocesos. Por lo que no puede ser que ...
benjismith
49
El tamaño del montón reduce el espacio de direcciones disponible para las pilas. El espacio de direcciones de 256K / stack tiene sentido.
Tom Hawtin - tackline
1
Sí, esto muestra lo mismo pequenoperro.blogspot.com/2009/02/less-is-more.html
Toby
39

Sé que esta pregunta es bastante antigua, pero solo quiero compartir mis hallazgos.

Mi computadora portátil es capaz de manejar un programa que genera 25,000hilos y todos esos hilos escriben algunos datos en la base de datos MySql a intervalos regulares de 2 segundos.

Ejecuté este programa con 10,000 threadspara 30 minutes continuouslyentonces también mi sistema era estable y pude hacer otras operaciones normales como navegar, abrir, cerrar otros programas, etc.

Con 25,000 threadssistema slows downpero sigue siendo sensible.

Con el 50,000 threadssistema al stopped respondinginstante y tuve que reiniciar mi sistema manualmente.

Los detalles de mi sistema son los siguientes:

Processor : Intel core 2 duo 2.13 GHz
RAM : 4GB
OS : Windows 7 Home Premium
JDK Version : 1.6

Antes de ejecutar configuré el argumento jvm -Xmx2048m.

Espero eso ayude.

Shekhar
fuente
2
"Retarda" suena como un intercambio.
Thorbjørn Ravn Andersen
Gracias. Era una máquina bastante sólida y funcionó bien durante casi 8 años hasta que de repente dejó de arrancar. Acabo de instalar Ubuntu en él en lugar de Windows y comenzó a descifrar números nuevamente :)
Shekhar
Fried core 2 duo con condimento ubuntu: D
Pasupathi Rajamanickam
31

El máximo teórico absoluto es generalmente el espacio de dirección de usuario de un proceso dividido por el tamaño de la pila de hilos (aunque en realidad, si toda su memoria está reservada para las pilas de hilos, no tendrá un programa que funcione ...).

Entonces, en Windows de 32 bits, por ejemplo, donde cada proceso tiene un espacio de dirección de usuario de 2 GB, lo que le da a cada subproceso un tamaño de pila de 128K, esperaría un máximo absoluto de 16384 subprocesos (= 2 * 1024 * 1024/128). En la práctica, encuentro que puedo iniciar unos 13,000 bajo XP.

Entonces, creo que eres en esencia en si (a) se puede administrar malabarismo que muchos hilos en el código y no hacen cosas tontas, obviamente, (como haciendo que todos se espera en el mismo objeto a continuación, llamar notifyAll () ...), y (b) si el sistema operativo puede. En principio, la respuesta a (b) es "sí" si la respuesta a (a) también es "sí".

Por cierto, puede especificar el tamaño de la pila en el constructor del subproceso ; no necesita (y probablemente no debería) meterse con los parámetros de VM para esto.

Neil Coffey
fuente
1
Entonces use un sistema operativo de 64 bits. ¿Cuánto tiempo hemos estado usando procesadores de 64 bits por ahora?
Tom Hawtin - tackline el
Claro, solo estoy dando un ejemplo de un límite teórico vs práctico. Eso sí, todavía hay un montón de máquinas de 32 bits (incluidos servidores) ...
Neil Coffey
2

Recuerdo haber escuchado una charla de Clojure donde pudo ejecutar una de sus aplicaciones en una máquina especializada en una feria con miles de núcleos (¿9000?), Y los cargó a todos. Desafortunadamente, no puedo encontrar el enlace en este momento (¿ayuda?).

Basado en eso, creo que es seguro decir que el hardware y su código son los factores limitantes, no la JVM.

Conocido
fuente
podrías mirar de nuevo? Me gustaría verlo: suena interesante y admite que los lenguajes funcionales son fáciles de escalar en todos los núcleos.
Thorbjørn Ravn Andersen
¿Puedes proporcionar un enlace a eso? Sé que Cliff Click, Jr., el ingeniero principal de Azul Systems, ejecutó la Simulación de colonias de hormigas de Rich Hickey en el sistema JCA más grande de Azul (Azul Vega 3 Series 7300 Modelo 7380D: AzulSystems.Com/products/compute_appliance_specs.htm ) con 864 núcleos y 768 GB de RAM, y las 700 hormigas lograron maximizar 700 núcleos. Pero 9000 núcleos, eso es bastante impresionante. ¿Qué tipo de máquina era esa?
Jörg W Mittag
Creo que fue la simulación de "hormigas". Aquí hay un enlace donde Rich Hickey (creador de Clojure) habla de esto: blip.tv/clojure/clojure-concurrency-819147 . Estaba en una gran caja de sistemas Azul con más de 800 núcleos, principalmente para demostrar cuán bueno es Clojure en el manejo de la concurrencia de múltiples núcleos.
mikera
@mikera lins ha expirado.
Thorbjørn Ravn Andersen
2

Después de jugar con la clase DieLikeACode de Charlie, parece que el tamaño de la pila de subprocesos de Java es una gran parte de la cantidad de subprocesos que puede crear.

-Xss establece el tamaño de la pila de hilos java

Por ejemplo

java -Xss100k DieLikeADog

Pero, Java tiene la interfaz Ejecutor . Lo usaría, podrá enviar miles de tareas Runnable y hacer que el Ejecutor procese esas tareas con un número fijo de subprocesos.

Steve K
fuente
13
¿Podemos llamarlo DieLikeACat? no estará vivo ni muerto hasta que lo ejecutes.
Goodwine
Gracias por señalar a los ejecutores, la gente debería usarlo con más frecuencia. Pero no funcionará si Runnable/ Callablerealmente necesita ejecutarse continuamente, como cuando tiene que manejar la comunicación. Pero es perfecto para consultas SQL.
Matthieu
0

Al menos en Mac OS X 10.6 32 bits, el sistema operativo tiene un límite (2560). Verifique este hilo de stackoverflow .

Jifeng Zhang
fuente
0

El número máximo de hilos depende de lo siguiente:

  • Configuración de hardware como microprocesador, RAM.
  • Sistema operativo como si es de 32 bits o de 64 bits
  • Código dentro del método de ejecución. Si el código dentro del método de ejecución es enorme, entonces el objeto de un solo hilo tendrá más requisitos de memoria
  • pgp
    fuente
    0

    Información adicional para sistemas linux modernos (systemd).

    Hay muchos recursos sobre esto de valores que pueden necesitar ajustes (como Cómo aumentar el número máximo de subprocesos JVM (Linux 64bit) ); sin embargo, se impone un nuevo límite mediante el límite systemd "TasksMax" que establece pids.max en el cgroup.

    Para las sesiones de inicio de sesión, el valor predeterminado de UserTasksMax es el 33% del límite del núcleo pids_max (generalmente 12,288) y se puede anular en /etc/systemd/logind.conf.

    Para los servicios, el valor predeterminado de DefaultTasksMax es el 15% del límite del núcleo pids_max (generalmente 4,915). Puede anularlo para el servicio configurando TasksMax en "systemctl edit" o actualizando DefaultTasksMax en /etc/systemd/system.conf

    Trent Lloyd
    fuente
    0

    Año 2017 ... clase DieLikeADog.

    Nuevo hilo # 92459 Excepción en el hilo "principal" java.lang.OutOfMemoryError: no se puede crear un nuevo hilo nativo

    i7-7700 16 gb de ram

    Adeptius
    fuente
    Las respuestas fuera del curso variarán. Tengo 10278 con 6 GB de RAM.
    jamie
    -4

    Puede procesar cualquier cantidad de hilos; No hay límite. Ejecuté el siguiente código mientras veía una película y usaba NetBeans, y funcionó correctamente / sin detener la máquina. Creo que puedes mantener aún más hilos que este programa.

    class A extends Thread {
        public void run() {
            System.out.println("**************started***************");
            for(double i = 0.0; i < 500000000000000000.0; i++) {
                System.gc();
                System.out.println(Thread.currentThread().getName());
            }
            System.out.println("************************finished********************************");
        }
    }
    
    public class Manager {
        public static void main(String[] args) {
            for(double j = 0.0; j < 50000000000.0; j++) {
                A a = new A();
                a.start();
            }
        }
    }
    Anil Pal
    fuente
    77
    Sé que este comentario es muy tarde, pero creo que la razón por la que pudo iniciar y ejecutar estos muchos subprocesos es porque (suponiendo configuraciones de sistema normales y razonables) cada subproceso básicamente imprime una línea fuera de la salida y luego no tiene más razones para existe y es asesinado poco después, lo que garantiza una disponibilidad continua de recursos.
    ucsunil
    @ucsunil Eso no es cierto. Creo que has leído mal el código. Acabo de probarlo y los diferentes hilos están imprimiendo no solo la primera línea, sino también sus nombres. Lo que significa que están activos. Si pensabas que la recolección de basura reciclaría hilos sin referencia, no es así, mira aquí .
    Evgeni Sergeev
    1
    Sin embargo, después de poco tiempo, mainarrojará un mensaje OutOfMemoryErroren mi máquina, diciendo que no puede crear más hilos. Quizás @AnilPal, no lo notaste. Sugiero incluir otra declaración de impresión en el main(..)método, para ver claramente cuándo deja de crear nuevos hilos después de arrojar el error.
    Evgeni Sergeev
    55
    increíble ... un descubrimiento de la máquina real de Turing ... infinitos recursos.
    Josh