2009-09-18 6 views
11

Tengo esta aplicación web que necesita un ajuste de memoria. Aunque ya estoy perfilando la aplicación y recortando cosas, la JVM en sí misma me parece demasiado hinchada en nuestra instancia más ocupada. (Los casos de menor volumen no tienen este problema.) Los detalles:¿Qué impacto, si corresponde, tiene el conmutador -d64 en el uso de la memoria residente de Sun JVM?

  • Plataforma:
    • RHEL4 64 bits (Linux 2.6.9-78.0.5.ELsmp #1 SMP x86_64)
    • Sun Java 6 (Java HotSpot(TM) 64-Bit Server VM (build 10.0-b23, mixed mode))
    • Tomcat 6 con -d64 en startup.sh
  • Mi webapp actualmente tiene algún código que en producción requiere los beneficios de ejecutando 64 bits.
  • He observado que después de un tiempo (una semana) el tamaño de memoria residente de las JVM (como se muestra arriba) es tres veces el tamaño de mi configuración -Xmx.
  • El tamaño de la memoria no-montón, etc, son todos relativamente trivial, una mera porcentaje de un solo dígito del tamaño de la pila
  • Sólo hay una sección de código que requiere un espacio de dirección de bit de 64 bits

Si pudiera refactorizar la necesidad de una JVM de 64 bits y soltar el interruptor -d64, ¿eso reduciría la huella de memoria residente de la JVM? En otras palabras ...

¿Qué impacto, si lo hay, tiene el conmutador -d64 en el uso de la memoria residente de Sun JVM?

Respuesta

18

El uso del interruptor d64 coloca la JVM en el modo de 64 bits. Técnicamente, en Solaris/Linux y la mayoría de Unixes, el proceso de JVM se ejecutará en el modelo LP64.

La LP64 model es diferente del modelo de 32 bits (ILP32) en que los punteros son de 64 bits de ancho en comparación con los de 32 bits. Para la JVM, esto permite una mayor capacidad de direccionamiento de la memoria, pero también significa que el tamaño ocupado por las referencias de objeto solo se ha duplicado. Por lo tanto, hay una mayor hinchazón para el mismo número de objetos en un momento dado en una JVM de 32 bits y una de 64 bits.

Otra cosa que a menudo se olvida es el tamaño de las instrucciones. En una JVM de 64 bits, el tamaño de las instrucciones ocupará el tamaño del registro de la máquina nativa.

Sin embargo, si usa compressed object pointers en un entorno de 64 bits, la JVM codificará y descodificará los punteros siempre que sea posible para tamaños de almacenamiento dinámico superiores a 4 GB. En pocas palabras, cuando usa punteros comprimidos, la JVM intenta usar valores de 32 bits de ancho tanto como sea posible.

Sugerencia: Encienda el marcador UseCompressedOops, usando -XX: + UseCompressedOops para deshacerse de algunos de los gases. YMMV, pero people have reported upto 50% drop in memory bloat by using compressed oops.

EDITAR

The UseCompressedOops flag is supported in version 14.0 of the Java HotSpot VM, available from Java 6 Update 14 onwards.

+0

Fantástica respuesta. Me convenciste para refactorizar mi código y soltar el -d64. Volveré y comentaré cómo va.También trabajaré en una actualización de JVM para poder probar -XX: + UseCompressedOops. Gracias. ¡Has ganado * el premio Stu's World Famous "Impresionante codificador del mes" * de septiembre de 2009! –

+0

Guau, nunca supe que google-fu dilucidara tal reacción. Gracias, estoy sorprendido por tu respuesta! Por cierto, si logras mantener tu montón de menos de 4 GB, tu JVM de 64 bits se comportará como una de 32 bits; sin embargo, no estoy seguro de ningún impacto en el rendimiento. –

+0

Más que Google-fo !!! Miré a mi alrededor, y estaba * pensando * que valdría la pena el esfuerzo ... pero hay * tantos cambios en JVM, y valores, y casos si-luego-pero, y gotchyas. Puede ser abrumador, y mi necesidad fue una respuesta * "hazlo" */* "no molestar" *, acompañada de una alimentación relevante con cuchara. Gracias de nuevo. –

Cuestiones relacionadas