2011-09-22 14 views
71

¿Puede alguien explicar cuál es la opción de JVM ReservedCodeCacheSize y InitialCodeCacheSize? Específicamente cuándo/por qué querría cambiarlo? ¿Cómo decido cuál es el tamaño correcto?¿Qué son ReservedCodeCacheSize y InitialCodeCacheSize?

Esto es lo que dicen los documentos:

-XX: ReservedCodeCacheSize = 32m Reservados tamaño de la caché de código (en bytes) - tamaño máximo de caché de código. [Solaris de 64 bits, amd64 y -server x86: 2048m; en 1.5.0_06 y anteriores, Solaris de 64 bits y and64:. 1024m]

+2

El OP de esta publicación escribió:> -XX: ReservedCodeCacheSize = 32m Tamaño de caché de código reservado (en bytes) - tamaño máximo de caché de código. [Solaris 64-bit, amd64 y -server x86: 48m; en 1.5.0_06 y anteriores, Solaris de 64 bits yy64: 1024m.] Solo quiero corregir que el límite superior mencionado a 48 m debe ser un error tipográfico. Son 2048m. –

Respuesta

66

ReservedCodeCacheSize (y InitialCodeCacheSize) es una opción para el compilador (just-in-time) de la máquina virtual Java HotSpot. Básicamente, establece el tamaño máximo para el caché de código del compilador.

La memoria caché puede llegar a ser completa, lo que da lugar a advertencias como las siguientes:

Java HotSpot(TM) 64-Bit Server VM warning: CodeCache is full. Compiler has been disabled. 
Java HotSpot(TM) 64-Bit Server VM warning: Try increasing the code cache size using -XX:ReservedCodeCacheSize= 
Code Cache [0x000000010958f000, 0x000000010c52f000, 0x000000010c58f000) 
total_blobs=15406 nmethods=14989 adapters=362 free_code_cache=835Kb largest_free_block=449792 

Es mucho peor cuando es seguida por Java HotSpot(TM) Client VM warning: Exception java.lang.OutOfMemoryError occurred dispatching signal SIGINT to handler- the VM may need to be forcibly terminated.

¿Cuándo establecer esta opción?

  1. al tener fallos hotspot compilador
  2. para reducir la memoria necesaria por la JVM (y por tanto con riesgo de fallos del compilador JIT)

Normalmente no cambiaría este valor. Creo que los valores predeterminados son bastante buenos porque estos problemas ocurren solo en muy raras ocasiones (en mi experiencia).

+1

Agradable. ¿Cuáles son los valores predeterminados y a qué se deberían aumentar si vemos que "CodeCache está lleno"? ¿advertencia? – axel22

+2

@ axel22: Los valores en realidad dependen de la plataforma y la versión de JVM; valores del doc para Sun JVM: 'Tamaño de caché de código reservado (en bytes): tamaño máximo de caché de código. [Solaris 64-bit, amd64 y -server x86: 48m; en 1.5.0_06 y anteriores, Solaris de 64 bits y amd64: 1024m.] 'No se conocen los valores de OpenJDK. Un aumento moderado debería ser suficiente (un ajuste anterior de 1024m fue más que bueno y malo). – jeha

12

@jeha responde todo lo que quería saber a partir de esta pregunta, aparte del valor para establecer los parámetros. Como no escribí el código que estaba implementando, no tenía mucha visibilidad de la huella de memoria que tenía.

Sin embargo, puede usar jconsole para adjuntarlo a su proceso java en ejecución, y luego usar la pestaña 'Memoria' para averiguar el tamaño de la caché de código. Para completar, los pasos son (entorno Linux VM, aunque estoy seguro de que otros ambientes son similares):

  1. fuego hasta jconsole en su máquina
  2. buscar el identificador de proceso derecha y una jconsole a ella (esto tome unos momentos)
  3. Vaya a la pestaña 'memoria'
  4. Desde el 'Mapa:' lista desplegable, seleccione 'memoria piscina 'caché Código''
  5. de nuevo, esto puede tardar unos momentos para que la pantalla se actualice, y luego debería ver algo como: jconsole code cache image

    Como puede ver, mi código de caché utiliza aproximadamente 49 MB. En este punto todavía tenía el valor predeterminado que la documentación (y @jeha) dice que es de 48 MB. Sin duda una gran motivación para mí para aumentar el ajuste!

    Ben.


    1024 MB de forma predeterminada, probablemente, era la exageración de ella, pero 48 MB por defecto parece estar underdoing que ...

+0

Buena sugerencia ... Estoy intentando con -J-XX: ReservedCodeCacheSize = 512m – MarcoZen

+0

Netbeans no comenzaría con 512m, lo hice con 256m – MarcoZen

+0

Y después de probar durante aproximadamente 2 días puedo decir que la configuración no mostró ninguna/ninguna mejora notable y en su lugar hizo borracho Netbeans. Terminé simplemente quitándolo. – MarcoZen

11

Cuando la JVM compila el código, se cumple el conjunto de instrucciones en lenguaje ensamblador en la memoria caché código. El caché de código tiene un tamaño fijo, y una vez que se ha completado, la JVM no es capaz de compilar ningún código adicional.

El tamaño máximo de la memoria caché de código se establece a través de -XX: ReservedCodeCacheSize = N flag (donde N es el valor predeterminado que se acaba de mencionar para el compilador en particular). El caché de código es administrado como la mayoría de la memoria en la JVM: hay un tamaño inicial ( -XX: InitialCodeCacheSize = N). La asignación del tamaño de la memoria caché de código comienza en el tamaño inicial de y aumenta a medida que se llena el caché. El tamaño inicial de la memoria caché de código varía según la arquitectura de chip y compilador en uso. Cambiar el tamaño de la memoria caché sucede en segundo plano y no afecta realmente al rendimiento, por lo que establecer el tamaño ReservedCodeCacheSize (es decir, establecer el tamaño máximo de caché de código) es todo lo que es generalmente necesario.

De forma predeterminada para el servidor de 64 bits, el tamaño de Java 7 es de 48 MB (con una compilación por niveles de 96 MB). En Java 8 para el servidor de 64 bits, el tamaño de la memoria es de 240 MB.

- Pinaki

+2

+1 por mencionar la diferencia de tamaño de Java 7/Java 8. Sospecho que esto se debe a que la compilación por niveles está activada por defecto en Java 8. – jdv

+0

Está correcto, la compilación escalonada se estabilizó después de 1.7.40 antes de que tengan algunos problemas. La compilación escalonada puede usar fácilmente todo el caché de código en su configuración predeterminada, por lo tanto, lo aumentaron a un nivel más seguro en Java8. –

1

Una buena experiencia de aprendizaje de hecho el equipo de ingeniería y los desafíos que enfrenta al migrar a jdk 8.

http://engineering.indeedblog.com/blog/2016/09/job-search-web-app-java-8-migration/

Conclusión: Jdk 8 necesita más caché de código de han JDK 7

El tamaño predeterminado de la memoria caché para JRE 8 es de aproximadamente 250 MB, aproximadamente cinco veces más grande que el valor predeterminado de 48 MB para JRE 7. Nuestra experiencia es que JRE 8 necesita ese código adicional. Hasta el momento hemos cambiado aproximadamente diez servicios a JRE 8, y todos ellos usan cuatro veces más codecache que antes.

0

de https://blogs.oracle.com/poonam/entry/why_do_i_get_message:

Los siguientes son dos problemas conocidos en jdk7u4 + con respecto al lavado CodeCache:

  1. El compilador no puede quedar reiniciado incluso después de la ocupación CodeCache desciende a casi la mitad después del enjuague de emergencia.
  2. El enjuague de emergencia puede causar un alto uso de la CPU por parte de los subprocesos del compilador, lo que conduce a una degradación general del rendimiento.

Este problema de rendimiento, y el problema de que el compilador no se vuelva a habilitar de nuevo se ha abordado en JDK8. Para solucionar estos problemas en JDK7u4 +, podemos aumentar el tamaño de la memoria caché de código utilizando la opción ReservedCodeCacheSize, estableciéndola en un valor mayor que la huella del código compilado para que la CodeCache nunca se llene. Otra solución para esto es deshabilitar la descarga de CodeCache usando la opción de JVM -XX: -UseCodeCacheFlushing.

Los problemas mencionados anteriormente se han corregido en JDK8 y sus actualizaciones.

De modo que la información puede valer la pena mencionar para los sistemas que se ejecutan en JDK 6 (teniendo código de lavado deshabilitado) y 7.

Cuestiones relacionadas