2009-03-08 11 views
21

He leído muchos artículos acerca de la sintonización de GC en Java y me he preguntado cuántas personas realmente utilizan algunas de las características más avanzadas.¿Alguien ha encontrado que la recolección de basura sea útil?

Siempre he evitado el ajuste siempre que sea posible y me he concentrado en escribir el código más simple posible (consejo de Brian Goetz): esto parece haber funcionado bien para mí hasta ahora.

¿Estas estrategias de ajuste son resistentes para cambiar en las versiones de VM o requieren una reevaluación constante?

El único ajuste que he utilizado es el indicador -server.

+0

Tenga en cuenta que el indicador -server generalmente no es necesario si realmente se está implementando en un servidor. La JVM detectará qué tipo de entorno se está ejecutando en –

+1

Esto no funciona en Windows. Aunque funciona en Linux y Solaris. La mayoría de los cuadros de Windows superan los requisitos del servidor estándar. Presumiblemente, la suposición es que se usarán para el uso del cliente. – Fortyrunner

Respuesta

20

Parte de mi trabajo actual es el cuidado y la alimentación de una gran aplicación java que fue diseñada para funcionar con una gran cantidad de memoria (actualmente 8 Gb), principalmente debido a los cálculos en curso con muchos datos en caché. Hice la implementación inicial con la configuración de GC estándar, sobre todo porque no había una forma sencilla de simular el entorno de producción que se ejecuta a máxima velocidad.

En etapas, en los próximos meses, he personalizado la configuración del GC. En general, la perilla más grande disponible parece estar ajustando la frecuencia y la magnitud de incrementos de gc; la mayor mejora ha sido el intercambio de grandes gc periódicos para los más pequeños y más frecuentes. Pero definitivamente hemos podido ver mejoras en el rendimiento.

No voy a publicar mis configuraciones específicas porque a) son específicas de nuestra configuración, yb) porque no las tengo a mano :). Pero, en general, lo que he encontrado es

  • que ha habido una gran cantidad de trabajo realizado en afinar los ajustes por defecto de la cromatografía gaseosa. Casi siempre los valores predeterminados funcionan mejor que cualquier ajuste que realice.
  • Al menos para mí, las situaciones en las que sintonía GC era realmente la pena eran lo suficientemente extrema que era descabellado intento de simular ellos, así que tuve que hacerlo experimentalmente y de manera progresiva.

Here's una buena referencia de un anterior. discusión de stackoverflow.

8

Debo decir que no he tenido la necesidad de utilizar la sintonización mucho. Pero trabajo estrechamente con personas que escriben código donde la latencia es crítica: usan mucho esa afinación, especificando qué algoritmo de GC usar, tiempos máximos de pausa, proporciones de sobrevivientes, etc.

Supongo que la respuesta es por lo tanto: if latencia es crítica para una aplicación, es posible que tenga que ver la sintonización de su GC

10

La gran mayoría de los desarrolladores nunca tendrán que (o desean) ajustar GC. He trabajado con personas que han tenido templarlo y aquí está el consejo:

Antes de intentar ajustar la basura colector hacer 100% seguro de que han verificado , con un generador de perfiles. ¿Qué está pasando ? Una vez que comience a sintonizar, asegúrese de que verifique, con un generador de perfiles, que tuvo un efecto positivo.

También debe volver a visitar los cambios con cada versión de la máquina virtual que ejecuta (diferentes máquinas virtuales tendrán diferentes estrategias de ajuste).

Una vez ayudé a alguien con un problema de GC que resultó ser que no estaban cerrando conjuntos de resultados JDBC (o algún problema como ese). Esto causó que la memoria nunca se liberara (su código se mantuvo sobre ellos por alguna razón). La solución de ese problema hizo que el programa pasara de 20 minutos a algo así como 30 segundos o un par de minutos. El uso de la memoria también bajó.

+0

Eso es lo que me preocupa. Cualquier estrategia de ajuste deberá verificarse siempre que se produzca una versión de JVM e incluso a intervalos regulares a lo largo del ciclo de desarrollo; por eso evito el ajuste. – Fortyrunner

+0

La máquina virtual es volátil, realizan cambios/mejoras en GC con cada versión, por lo que incluso las "leyendas urbanas" sobre mejoras de rendimiento probablemente sean incorrectas cuando las escuche ... siempre escriba su código limpio y es probable que sea rápido suficiente, si no, será más fácil acelerarlo. – TofuBeer

3

Yo diría que lo más común de sintonizar es el tamaño máximo de la memoria. La mayoría de las otras opciones de memoria tienen valores predeterminados razonables y a menudo están sobreajustados en mi humilde opinión. Es decir, establecer cuando realmente no hace mucha diferencia. A menudo veo que las personas configuran muchas opciones cuando la mitad de ellas son las predeterminadas en cualquier caso. ;)

El uso de un generador de perfiles es la forma más útil para mejorar el comportamiento GC (al reducir el número de objetos creados)

+0

No estoy seguro de que la mayoría de las personas vean configurar el parámetro Xmx como "ajuste" de GC. –

+0

No estoy de acuerdo un poco. Si tiene un cuadro ocupado y asigna demasiada memoria, esto puede provocar que la caja intercambie demasiada memoria. – Fortyrunner

+1

Buenos puntos, el uso de -mx puede no ser considerado ajuste de GC, pero a menudo es lo único que necesita para hacerlo bien. Como señala @Fortyrunner, no desea que sea demasiado grande o demasiado pequeño. Descubrí que no desea que la JVM use más de un banco de memoria si puede evitarlo. –

3

tengo pero no recientemente. La aplicación en la que estaba trabajando era la reproducción en tiempo real de una secuencia de video construida con imágenes JPEG de movimiento individuales. En ese momento (alrededor de JDK 1.2 y 1.3), la configuración -Xincgc cambiaría al recolector de basura del cliente de una limpieza más grande a un modo en el que se limpiaba un poco de basura regularmente. Como resultado, la distribución de las latencias de trama fue mucho menor, dando la impresión de un video más suave (en lugar de 1-2-3-pausa, 1-2-3-pausa).

No he visto ese código en bastante tiempo, pero sospecho firmemente que, con los algoritmos modernos de recolección de basura, -Xincgc realmente disminuiría el rendimiento.

En el mundo de hoy, yo diría que el escepticismo de optimización estándar siempre debería aplicarse: perfil de perfil. ¿Estás seguro de que el cuello de botella es realmente el recolector de basura ...?

+0

Probablemente disminuya el rendimiento general, pero aún así podría mejorar mucho la latencia.El recuento de referencias de C++ shared_ptr, por ejemplo, puede ser más lento que Java GC, pero el efecto general es * mucho más suave *. –

+0

@ Zan, no creo entender su comentario. Lo que estaba diciendo era que -Xincgc ahora es demasiado ingenuo. El GC moderno tiene opciones más útiles. Ni siquiera llegaría a la conclusión de que -Xincgc daría lugar a latencias más suaves sin pruebas. –

+0

El punto de mi comentario fue que hacer pequeñas limpiezas continuas puede hacer que la aplicación tarde más en ejecutarse, pero será más agradable de usar (si la aplicación es interactiva con el usuario). –

2

En resumen, sí, es muy útil para sintonizar cualquier aplicación Java seria. A menudo hemos encontrado que en los escenarios de producción es la diferencia entre una aplicación estable y una completamente impredecible. Ciertamente, no es lo primero que hago, pero una vez que tiene una aplicación funcionando y puede aplicarle una carga real, es una de las primeras cosas que debe investigar en ese momento.

Cuestiones relacionadas