2009-12-22 6 views
6

En una máquina Windows de 64 bits con 12 GB de RAM y 33 GB de memoria virtual (por administrador de tareas), puedo ejecutar Java (1.6.0_03-b05) con una configuración imposible -Xmx de 3.5TB pero falla con 35TB. ¿Cuál es la lógica detrás de cuándo funciona y cuándo falla? El error en 35TB parece implicar que está tratando de reservar espacio al inicio. ¿Por qué haría eso para -Xmx (a diferencia de -Xms)?¿Por qué puedo configurar -Xmx en un valor mayor que la memoria física y virtual en la máquina tanto en Windows como en Solaris?

 
C:\temp>java -Xmx3500g ostest 
os.arch=amd64 
13781729280 Bytes RAM 

C:\temp>java -Xmx35000g ostest 
Error occurred during initialization of VM 
Could not reserve enough space for object heap 
Could not create the Java virtual machine. 

En Solaris (4 GB de RAM, Java 1.5.0_16), que prácticamente se rindieron a 1 PB de qué tan alto que puedo establecer -Xmx. No entiendo la lógica de cuándo saldrá el error en la configuración -Xmx.

 
devsun1.mgo:/export/home/mgo> java -d64 -Xmx1000000g ostest 
os.arch=sparcv9 
4294967296 Bytes RAM 

Respuesta

11

Al menos con Sun VM de 64 bits 1.6.0_17 para Windows, ObjectStartArray :: initialize asignará 1 byte por cada 512 bytes de heap en el inicio de VM. Iniciar la máquina virtual con un montón de 35TB hará que la VM asigne 70 GB inmediatamente y, por lo tanto, falle en su sistema.

La máquina virtual de 32 bits (y supongo que la máquina virtual de 64 bits) de Sun no tiene en cuenta la memoria física disponible al calcular el máximo almacenamiento dinámico, pero solo está limitada por la memoria direccionable de 2GB en Windows y Linux o 4 GB en Solaris o posiblemente no pueda asignar suficiente memoria al inicio para el área de administración.

Si lo piensas bien, no tiene mucho sentido verificar la cordura del valor máximo de almacenamiento dinámico contra la memoria física disponible. X GB de memoria física no significa que X GB esté disponible para la VM cuando sea necesario, sino que también puede haber sido utilizada por otros procesos, por lo que la VM necesita una forma de lidiar con la situación en la que se requiere más almacenamiento que el disponible el sistema operativo de todos modos. Si la VM no está rota, se lanzan OutOfMemoryErrors si la memoria no se puede asignar desde el sistema operativo, como si se hubiera alcanzado el tamaño máximo de almacenamiento dinámico.

8

Según this thread en los foros de Java de Sun (el PO tiene 16 GB de memoria física):

Podría especificar -Xmx20g, pero si el total de la memoria necesaria por todos los procesos en su la máquina excede la memoria física en su máquina, es probable que termine paginando. Algunas aplicaciones pueden sobrevivir ejecutarse en la memoria paginada, pero la JVM no es una de ellas. Su código podría funcionar bien, pero, por ejemplo, las recolecciones de basura serán abismalmente lentas.

ACTUALIZACIÓN: Busqué en Google un poco más y, de acuerdo con el Frequently Asked Questions About the Java HotSpot VM y más precisamente How large a heap can I create using a 64-bit VM?

¿Qué tan grande un montón puedo crear usando una máquina virtual de 64 bits?

en 64 bits máquinas virtuales, que tienen 64 bits de direccionamiento de para trabajar con resultando en un tamaño máximo de almacenamiento dinámico de Java limitada sólo por la cantidad de memoria física y espacio de intercambio su sistema proporciona.
Ver también Why can't I get a larger heap with the 32-bit JVM?

No sé por qué usted es capaz de iniciar una JVM con un montón> 45GB. Esto es un poco confuso ...

1

Solo para reforzar la respuesta de Pascal: tenga mucho cuidado en las ventanas cuando especifique un tamaño de memoria máximo alto. Estaba trabajando en un proyecto de servidor que requería tanta memoria física como sea posible, pero una vez que está sobre el ram físico, el rendimiento abismal no es una buena descripción de lo que sucede, la máquina colgada podría ser mejor.

Lo que sucede (al menos esta es mi evaluación después de días de examinar registros y volver a ejecutar pruebas) es que Windows se queda sin memoria RAM y pide a todas las aplicaciones que liberen lo que puedan. Cuando se le pregunta a Java, Java inicia un GC. El GC toca toda la memoria (lo que hace que se intercambie todo lo que se ha intercambiado). Esto a su vez hace que las ventanas se queden sin memoria. Windows luego envía un mensaje a todas las aplicaciones pidiéndoles que liberen todo lo que puedan .... (recurse indefinidamente)

Esto puede no ser REALMENTE lo que está sucediendo, pero el hecho de que Java GC toca memorias muy antiguas a veces lo hace incompatible con paginación.

Cuestiones relacionadas