No conozco ninguna herramienta/utilidad que funcione con las JVM de generación actual.
Pero la otra cara es que no veo cómo una utilidad así sería útil.
Los tiempos de GC largos suelen ocurrir porque el montón está demasiado lleno. A medida que el montón se aproxima al 100%, la cantidad de tiempo que pasa en el GC tiende a crecer exponencialmente. En el peor de los casos, el montón se llena por completo y tu aplicación obtiene un OutOfMemoryError
. Hay dos soluciones posibles:
Si la causa es que el montón es demasiado pequeña (para el tamaño del problema que su aplicación está tratando de resolver) a continuación, o bien aumentar el tamaño del montón, o buscar una manera para reducir el conjunto de trabajo de la aplicación; es decir, el número/tamaño de objetos que necesita tener "en vivo" durante el cálculo.
Si la causa raíz es una pérdida de memoria, instálela y solucionela.
En ambos casos, el uso de un analizador de memoria le ayudará a analizar el problema. Pero no necesita saber qué objetos están en la generación anterior. No es relevante ni para la causa raíz del problema ni para la solución del problema.
Quiero saber qué objetos son los "supervivientes" que permanece en la zona vieja, con el fin de saber qué la creación de objetos para optimizar.
Esto está empezando a tener más sentido. Parece que necesita averiguar qué objetos son de larga vida ... en lugar de específicamente en qué espacio viven. Podría hacerlo usando jhat
para comparar una secuencia de instantáneas de montón. (Puede haber una manera mejor ...)
Sin embargo, todavía no creo que este enfoque sea útil. El problema es que un GC completo debe atravesar todos los objetos alcanzables (duros, blandos, débiles, fantasmas). Y si tienes un montón de 32Gb que está lleno al 30%, todavía tienes muchos objetos para marcar/barrer/reubicar. Creo que es probable que la solución sea utilizar un recopilador concurrente y ajustarlo para que pueda mantenerse al día con la tasa de asignación de objetos de su aplicación.
También parece que está llamando al System.gc()
directamente desde su código. ¡No hagas eso! Llamar a System.gc()
provocará (normalmente) que la JVM realice una recolección de basura completa. Eso es más o menos garantizado para darle una pausa.Es mucho mejor dejar la JVM para decidir cuándo ejecutar el recopilador.
Por último, no está claro a qué se refiere con "optimización de la creación de objetos". ¿Quiere decir reducir la tasa de creación de objetos? ¿O estás pensando en otra cosa para gestionar la retención de objetos de larga vida (en caché?).
Solo he usado [Visualvm] (http://docs.oracle.com/javase/6/docs/technotes/guides/visualvm/intro.html), [Visualgc] (http: //java.sun. com/performance/jvmstat/visualgc.html) y [Jconsole] (http://docs.oracle.com/javase/1.5.0/docs/guide/management/jconsole.html#gc). No recuerdo que ninguno de ellos pudiera enumerar los objetos ocupados. Sin embargo, le darán algunas estadísticas sobre el área ocupada. Así que solo recomiendo este artículo http://java.sun.com/docs/hotspot/gc/index.html y +1 – bpgergo
¿Cuál es su conjunto completo de parámetros de inicio de JVM? – moodywoody