new - ¿Cuántos subprocesos puede admitir una VM Java?
new icon java (13)
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 ram
¿Cuántos subprocesos puede admitir una VM Java? ¿Esto varía según el vendedor? por el sistema operativo? ¿otros factores?
Al menos en Mac OS X 10.6 32 bits, hay un límite (2560) en el sistema operativo. Verifique este hilo de .
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 del hilo de Java
Por ejemplo
java -Xss100k DieLikeADog
Pero, Java tiene la interfaz Executor . Lo usaría, podrá enviar miles de tareas Ejecutables, y el Ejecutor procesará esas tareas con un número fijo de hilos.
Después de leer la publicación de Charlie Martin, tenía curiosidad sobre si el tamaño del montón hace alguna diferencia en la cantidad de hilos que puedes crear, y el resultado me dejó atónito.
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 del montón y el recuento máximo de hilos es INVERSAMENTE proporcional.
Lo cual es extraño.
El máximo teórico absoluto es generalmente el espacio de direcciones de usuario de un proceso dividido por el tamaño de la pila de subprocesos (aunque en realidad, si toda su memoria está reservada para pilas de subprocesos, no tendrá un programa en funcionamiento ...).
Por lo tanto, en Windows de 32 bits, donde cada proceso tiene un espacio de direcciones de usuario de 2 GB, lo que da un tamaño de pila de 128K a cada subproceso, esperaría un máximo absoluto de 16384 subprocesos (= 2 * 1024 * 1024/128). En la práctica, me parece que puedo comenzar alrededor de 13,000 bajo XP.
Entonces, creo que esencialmente te interesa si (a) puedes manejar malabares con muchos hilos en tu código y no hacer cosas tontas (como hacer que todos esperen el mismo objeto y luego llamar a 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, puedes especificar el tamaño de la pila en el constructor del Thread ; no es necesario (y probablemente no debería) meterse con los parámetros de VM para esto.
El número máximo de hilos depende de lo siguiente:
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> 6500 subprocesos antes de cerrar 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 Threads (en Java), toda la máquina comenzó a tener problemas y se volvió inestable.
Mi experiencia muestra que Java (versiones recientes) puede consumir tantos hilos 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 están haciendo los Threads y tener una pila para cada Thread. Cualquier máquina con una CPU moderna (las generaciones de generaciones más recientes de AMD o Intel) y con 1 - 2 gigas de memoria (según el 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.
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 de JVM (Linux de 64 bits) ); sin embargo, se impone un nuevo límite por medio del límite "TasksMax" systemd que establece pids.max en el grupo cg.
Para las sesiones de inicio de sesión, el UserTasksMax predeterminado de UserTasksMax es el 33% del límite del kernel pids_max (generalmente 12,288) y puede anularse en /etc/systemd/logind.conf.
Para los servicios, DefaultTasksMax defecto es 15% del límite del kernel pids_max (usualmente 4,915). Puede anularlo para el servicio configurando TasksMax en "systemctl edit" o actualizando DefaultTasksMax en /etc/systemd/system.conf
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 puede 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();
}
}
}
Recuerdo haber escuchado una charla de Clojure donde pudo ejecutar una de sus aplicaciones en una máquina especializada en una feria comercial con miles de núcleos (¿9000?) Y las cargó todas. Desafortunadamente, no puedo encontrar el enlace ahora mismo (¿ayuda?).
Basado en eso, creo que es seguro decir que el hardware y su código son los factores limitantes, no la JVM.
Sé que esta pregunta es bastante antigua, pero solo quiero compartir mis hallazgos.
Mi computadora portátil es capaz de manejar programas que generan 25,000
hilos 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 threads
durante 30 minutes continuously
luego también mi sistema se mantuvo estable y pude realizar otras operaciones normales como navegar, abrir, cerrar otros programas, etc.
Con 25,000 threads
sistema se slows down
pero sigue siendo receptivo.
Con 50,000 threads
sistema stopped responding
instante 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, establecí el argumento jvm -Xmx2048m
.
Espero eso ayude.
Um, mucho.
Hay varios parámetros aquí. La máquina virtual específica, además, generalmente también hay parámetros de tiempo de ejecución en la máquina virtual. Eso es algo impulsado por el sistema operativo: ¿qué soporte tiene el sistema operativo subyacente para los hilos y qué limitaciones les pone? Si la máquina virtual realmente utiliza hilos de nivel de sistema operativo, la buena idea de 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 te quejes por los pequeños detalles de sintaxis, estoy en mi primera taza de café), entonces seguramente deberías esperar cientos o miles de subprocesos en ejecución. Pero crear un Thread es relativamente costoso, y la sobrecarga del programador puede ser intensa; no está claro que puedas hacer que esos hilos hagan algo útil.
Actualizar
De acuerdo, no pude resistir. 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
New thread #2547 New thread #2548 New thread #2549 Can''t create thread: 5 New thread #2550 Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread at java.lang.Thread.start0(Native Method) at java.lang.Thread.start(Thread.java:592) at DieLikeADog.main(DieLikeADog.java:6)