modify increase change aumentar java memory jvm

increase - ¿Cómo Java(JVM) asigna la pila para cada hilo?



limit heap size java (2)

Una aplicación Java se inicia con un montón para todos los subprocesos. Cada hilo tiene su propia pila.

Cuando se inicia una aplicación Java, usamos la opción JVM -Xms y -Xmx para controlar el tamaño del montón y -Xss para controlar el tamaño de la pila.

Según tengo entendido, el montón que se crea se convierte en una memoria "administrada" de JVM y todos los objetos que se crean se colocan allí.

Pero, ¿cómo funciona la creación de pila? ¿Java crea una pila para cada hilo cuando se crea? Si es así, ¿dónde está exactamente la pila en la memoria? Ciertamente no está en el montón "gestionado".

¿Crea la pila JVM desde la memoria nativa o asigna previamente una sección del área de memoria administrada para la pila? Si es así, ¿cómo sabe JVM cómo se crearán los hilos?


JVM usa más memoria que solo el montón. Por ejemplo, los métodos Java, las pilas de hilos y los manejadores nativos se asignan en la memoria por separado del montón, así como las estructuras de datos internas de la JVM.

(Source) .

Así que para responder a sus preguntas:

¿Java crea una pila para cada hilo cuando se crea?

Sí.

Si es así, ¿dónde está exactamente la pila en la memoria?

En la memoria asignada de la JVM, pero no en el montón.

Si es así, ¿cómo sabe JVM cómo se crearán los hilos?

No lo hace

Puede crear tantos como desee hasta que haya agotado su memoria JVM y obtenga

Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread

EDITAR:

Todo lo anterior se refiere a Jrockit JVM, aunque me resulta difícil creer que otras JVM serían diferentes en estos temas fundamentales.


Hay algunas cosas sobre las pilas de hilos que la especificación de Java nos dice. Entre otras cosas:

  • Cada subproceso de Java Virtual Machine tiene una pila privada de Java Virtual Machine, creada al mismo tiempo que el subproceso.

  • Debido a que la pila de la Máquina Virtual de Java nunca se manipula directamente, excepto para los marcos de inserción y de apertura, los marcos pueden asignarse en montón. La memoria para una pila de máquinas virtuales Java no necesita ser contigua.

  • La especificación permite que las pilas de la Máquina Virtual Java sean de un tamaño fijo o que se expandan y contraigan dinámicamente según lo requiera el cálculo.

Ahora, si nos centramos en implementaciones de JVM como HotSpot, podemos obtener más información. Aquí hay algunos datos que he recogido de diferentes fuentes:

  • El tamaño mínimo de pila en HotSpot para un hilo parece ser fijo. Esto es para lo que está mencionada la opción -Xss . (Source)

En Java SE 6, el valor predeterminado en Sparc es 512k en la máquina virtual de 32 bits y 1024k en la máquina virtual de 64 bits. ... Puede reducir el tamaño de su pila ejecutando con la opción -Xss. ... 64k es la menor cantidad de espacio de pila permitido por subproceso.

  • JRockit asigna memoria separada del montón donde se encuentran las pilas. (Source)

Tenga en cuenta que la JVM utiliza más memoria que solo el montón. Por ejemplo, los métodos Java, las pilas de hilos y los manejadores nativos se asignan en la memoria por separado del montón, así como las estructuras de datos internas de la JVM.

  • Existe una asignación directa entre un subproceso de Java y un subproceso de sistema operativo nativo en HotSpot. (Source) .

  • Pero la pila de hilos de Java en HotSpot está administrada por software, no es una pila de hilos nativos del sistema operativo. (Source)

Utiliza una pila de software separada para pasar los argumentos de Java, mientras que la propia VM utiliza la pila C nativa. Una serie de variables internas de JVM, como el contador del programa o el puntero de pila para un subproceso de Java, se almacenan en variables C, que no se garantiza que siempre se mantengan en los registros de hardware. La administración de estas estructuras de intérpretes de software consume una parte considerable del tiempo total de ejecución.

  • JVM también utiliza la misma pila de subprocesos de Java para los métodos nativos y las llamadas de tiempo de ejecución de JVM (por ejemplo, carga de clases). (Source) .

  • Curiosamente, incluso los objetos asignados a veces pueden ubicarse en la pila en lugar del montón como una optimización del rendimiento. (Source)

Las JVM pueden usar una técnica llamada análisis de escape, mediante la cual pueden decir que ciertos objetos permanecen confinados en un solo hilo durante toda su vida útil, y que la vida útil está limitada por la vida útil de un marco de pila determinado. Dichos objetos se pueden asignar de forma segura en la pila en lugar del montón.

Y como una imagen vale más que mil palabras, aquí hay una de (Source)

Ahora respondiendo algunas de tus preguntas:

¿Cómo sabe JVM cómo se crearán los hilos?

No lo hace Se puede demostrar fácilmente mediante la contradicción creando un número variable de subprocesos. Hace algunas suposiciones sobre el número máximo de subprocesos y el tamaño de pila de cada subproceso. Es por eso que puede quedarse sin memoria (¡no significa memoria de pila!) Si asigna demasiados hilos.

¿Java crea una pila para cada hilo cuando se crea?

Como se mencionó anteriormente, cada subproceso de Java Virtual Machine tiene una pila privada de Java Virtual Machine, creada al mismo tiempo que el subproceso. (Fuente) .

Si es así, ¿dónde está exactamente la pila en la memoria? Ciertamente no está en el montón "gestionado".

Como se indicó anteriormente, la especificación de Java permite que la memoria de pila se almacene en el montón, técnicamente hablando. Pero al menos JRockit JVM usa una parte diferente de la memoria.

¿Crea la pila JVM desde la memoria nativa o asigna previamente una sección del área de memoria administrada para la pila?

La pila está gestionada por JVM porque la especificación de Java prescribe cómo debe comportarse: una pila de Java Virtual Machine almacena marcos (§2.6). Una pila de máquinas virtuales Java es análoga a la pila de un lenguaje convencional . Una excepción son las pilas de métodos native utilizadas para native métodos native . Más sobre esto otra vez en la especificación .