shiginima premium poner pirata para memoria mas como aumentar asignar java memory-management jvm cluster-computing

java - premium - ¿JVM de 64 bits limitado a 300 GB de memoria?



como poner mas ram a minecraft 1.12 2 (5)

Estoy intentando ejecutar una aplicación Java en un entorno informático de clúster (IBM LSF ejecutando CentOS release 6.2 Final) que puede proporcionarme hasta 1TB de espacio RAM.

Podría crear una JVM con hasta 300 GB de memoria máxima (Xmx), aunque necesito más que eso (puedo proporcionar detalles, si se solicita).

Sin embargo, parece imposible crear una JVM con más de 300 GB de memoria máxima utilizando la opción Xmx. Para ser más específico, obtengo el mensaje de error clásico:

Se produjo un error durante la inicialización de la máquina virtual.

No se pudo reservar suficiente espacio para el montón de objetos.

Los detalles de mi JVM (de 64 bits) están a continuación:

Entorno de ejecución de OpenJDK (IcedTea6 1.10.6) (rhel-1.43.1.10.6.el6_2-x86_64)

OpenJDK 64-Bit Server VM (compilación 20.0-b11, modo mixto)

También lo intenté con una JVM Java 7 de 64 bits pero tuve exactamente el mismo problema.

Además, traté de crear una JVM para ejecutar HelloWorld.jar, pero aún la creación de JVM falla si pides más de -Xmx300G, así que no creo que tenga nada que ver con la aplicación específica.

¿Alguien tiene alguna idea de por qué no puedo crear una JVM con más de 300G de memoria máxima?

¿Alguien puede sugerir una solución / solución alternativa?


Ejecute ulimit -a como el usuario del Proceso de JVM y verifique que su kernel no esté limitando su tamaño máximo de memoria. Es posible que necesite editar /etc/security/limit.conf


Puedo pensar en un par de posibles explicaciones:

  • Otras aplicaciones en su sistema están usando tanta memoria que no hay 300 GB disponibles en este momento .

  • Podría haber un límite de recursos en el tamaño de la memoria por proceso. Puedes verificar esto usando ulimit . (Tenga en cuenta que de acuerdo con este error , obtendrá el mensaje de error si el límite de recursos por proceso detiene la JVM asignando las regiones de montón).

  • También es posible que se trate de un problema de "exceso de compromiso"; por ejemplo, si su aplicación se ejecuta en una virtual y el sistema en su conjunto no puede satisfacer la demanda porque hay demasiada competencia de otros virtuales.

Algunas de las otras ideas sugeridas son (IMO) poco probables:

  • Cambiar el JRE es poco probable que haga alguna diferencia. Nunca escuché ni vi los límites de memoria arbitrarios en JVM específicas de 64 bits.

  • Es poco probable que se deba a que no hay suficiente memoria contigua . Ciertamente, la memoria física contigua no es necesaria. La única posibilidad podría ser el espacio contiguo en el dispositivo de intercambio, pero no recuerdo que sea un problema para los sistemas operativos Linux típicos.

¿Alguien puede sugerir una solución / solución alternativa?

  • Verifica el ulimit .

  • Escriba un pequeño programa en C que intente malloc memoria y vea cuánto puede asignar antes de que falle.

  • Pídale ayuda al administrador del sistema (o hipervisor).


Según esta discusión , LSF no agrupa la memoria del nodo en un único espacio compartido. Estás usando algo más para eso. Lea la documentación de algo, porque es posible que no pueda hacer lo que le pide que haga. En particular, es posible que no pueda asignar una sola región contigua de memoria que abarque todos los nodos. Por lo general, eso no es necesario, ya que una aplicación hará muchas llamadas a malloc. Pero la JVM, para simplificar las cosas por sí misma, quiere asignar (o reservar) una sola región contigua para todo el montón llamando efectivamente a Malloc solo una vez. O podría ser algo más relacionado con lo que esté usando para emular una máquina gigante de memoria compartida.


Si echa un vistazo a la sección de preguntas frecuentes de Java HotSpot VM, menciona que en las máquinas virtuales de 64 bits, solo hay 64 bits de dirección para trabajar y, por lo tanto, el tamaño máximo de almacenamiento dinámico depende de la cantidad de memoria física y el espacio de intercambio. presente en el sistema.

Si calcula teóricamente, puede tener una memoria de 18446744073709551616 MB , pero existen limitaciones sobre ella.

-Xmx usar el comando -Xmx para definir el tamaño máximo de -Xmx dinámico para JVM. De forma predeterminada , Java usa 64 + 30% = 83.2MB en JVM de 64 bits.

Probé debajo del comando en mi máquina y parecía funcionar bien.

java -Xmx500g com.test.TestClass

También traté de definir un montón máximo en terabytes, pero no funciona.


(editado, ver la sección agregada en el espacio de intercambio)

SHMMAX y SHMALL

Dado que está utilizando CentOS, es posible que haya tenido un problema similar con respecto a la configuración del kernel SHMMAX y SHMALL , tal como se describe aquí para configurar Oracle DB . Debajo de ese mismo enlace hay un cálculo de ejemplo para obtener y establecer la configuración correcta de SHMALL .

Memoria contigua

Ciertos usuarios ya han informado que no hay suficiente memoria contigua disponible, otros han dicho que es irrelevante.

No estoy seguro si la JVM en CentOS requiere un bloque contiguo de memoria. Según SAS , la memoria fragmentada puede evitar que su JVM se inicie con un Xmx máximo Xmx o iniciar la Xms memoria Xms , pero otras afirmaciones en Internet dicen que no importa. Traté de probar o deshabilitar esa afirmación en mi estación de trabajo con Windows 48GB, pero logré iniciar la JVM con una configuración inicial y máxima de 40 GB. Estoy bastante seguro de que no hay ningún bloque contiguo de ese tamaño disponible, pero las JVM en diferentes sistemas operativos pueden comportarse de manera diferente, porque la administración de memoria puede ser diferente por SO (es decir, Windows normalmente oculta las direcciones físicas para procesos individuales).

Encontrar el bloque de memoria contiguo más grande

Utilice /proc/meminfo para encontrar el bloque de memoria contiguo más grande disponible, consulte el valor en VmAllocChunk . Aquí hay una guía y explicación de todos los valores. Si el valor que ve allí es más pequeño que VmAllocChunk , intente con un valor que VmAllocChunk justo debajo del valor de VmAllocChunk .

Sin embargo, generalmente este número es más alto que la memoria disponible físicamente (porque es el valor de memoria virtual disponible), puede darle un falso positivo. Es el valor que puede reservar, pero una vez que comience a usarlo, puede requerir el intercambio. Por lo tanto, también debe verificar los MemFree y Inactive . Por el contrario, también puede ver toda la lista y ver qué valores no superan los 300 GB.

Otras opciones de ajuste que puede verificar para JVM de 64 bits

No estoy seguro de por qué parece tener un límite de memoria de 300 GB. Por un momento pensé que podrías haber alcanzado un máximo de páginas. Con el valor predeterminado de 4kB, 300GB da 78,643,200 páginas. No parece un número mágico bien conocido. Si, por ejemplo, 2^24 es el máximo, entonces 16,777,216 páginas o 64 GB deberían ser el máximo teórico asignable.

Sin embargo, suponga que, por razones de argumento, necesita páginas más grandes (lo que resulta mejor para el rendimiento de las aplicaciones Java de memoria grande), debe consultar esta página de manual en JBoss , que explica cómo usar -XX:+UseLargePages y configure kernel.shmmax (allí está de nuevo), vm.nr_hugepages y vm.huge_tlb_shm_group (no estoy seguro de que esto último sea necesario).

Haga hincapié en su sistema

Otros han sugerido esto también. Para descubrir que el problema radica en la JVM y no en el sistema operativo, debe hacer una prueba de esfuerzo. Una herramienta que puedes usar es Stresslinux . En este tutorial , encontrará algunas opciones que puede usar. De particular interés para usted es el siguiente comando:

stress --vm 2 --vm-bytes 300G --timeout 30s --verbose

Si ese comando falla, o bloquea su sistema, usted sabe que el sistema operativo está limitando el uso de esa cantidad de memoria. Si tiene éxito, deberíamos intentar modificar la JVM de manera que pueda usar la memoria disponible.

EDITAR Apr6: verificar el espacio de intercambio

No es raro que los sistemas con tamaños de memoria interna muy grandes utilicen poco o ningún espacio de intercambio. Para muchas aplicaciones esto puede no ser un problema, pero la JVM requiere que el espacio de intercambio disponible sea mayor que el tamaño de memoria solicitado. De acuerdo con este informe de errores , la JVM intentará aumentar el espacio de intercambio en sí, sin embargo, como sugirieron algunas respuestas en este hilo SO , la JVM puede no ser siempre capaz de hacerlo.

Por lo tanto, verifique el espacio de intercambio actualmente disponible con cat /proc/swaps # free y, si es menor a 300 GB, siga las instrucciones en esta página de manual de CentOS para aumentar el espacio de intercambio para su sistema.

Nota 1: podemos deducir del informe de errores # 4719001 que un bloque contiguo de espacio de intercambio disponible no es una necesidad. Pero si no está seguro, elimine todo el espacio de intercambio y vuelva a crearlo , lo que debería eliminar cualquier fragmentación.

Nota 2: He visto varias publicaciones como esta que informan un espacio de intercambio de 0MB y pueden ejecutar la JVM. Eso probablemente se deba al hecho de que la JVM aumenta el espacio de intercambio en sí. Aún así, no está de más tratar de aumentar el espacio de intercambio a mano para averiguar si soluciona el problema.

Conclusión prematura

Me doy cuenta de que ninguna de las respuestas anteriores es una respuesta lista para usar. Espero que te dé algunos consejos sobre lo que puedes hacer para que funcione tu JVM. También puede probar otras JVM, si el problema resulta ser un límite de la JVM que está utilizando actualmente, pero por lo que he leído hasta ahora, no se debe imponer ningún límite para las JVM de 64 bits.

El error que se obtiene al inicializar la JVM me lleva a pensar que el problema no está en la JVM, sino que el sistema operativo no puede cumplir con la reserva de los 300 GB de memoria.

Mis propias pruebas mostraron que la JVM puede acceder a toda la memoria virtual y no le importa la cantidad de memoria física disponible. Sería extraño si la memoria virtual es más baja que la memoria física, pero la configuración de VmAllocChunk debería darle una pista en esa dirección (generalmente es mucho más grande).