2012-06-12 9 views
10

Tengo ciclos largos de GC. de las comprobaciones que vi que hay demasiados objetos en el área permanente (antigua) del Heap. ¿Hay alguna utilidad para saber qué objetos están en qué área del montón, o cualquier material estático sobre estos objetos.
Estoy usando Sun/Oracle HotSpot JVM (Java 6).hay una manera de saber qué objetos están en el área "vieja" de Heap

EDIT: poco más detalles acerca de mi problema:
Tengo un montón grande (32 GB) y parece que incluso cuando la zona vieja Montón es sólo el 30% de su capacidad, corriendo GC hacer manualmente las pausas de 15 segundos de. Quiero saber qué objetos son los "sobrevivientes" que quedan en el área anterior, para saber qué creación de objeto optimizar.

+1

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

+0

¿Cuál es su conjunto completo de parámetros de inicio de JVM? – moodywoody

Respuesta

7

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é?).

0

Nunca he visto una herramienta que permita "explorar" los objetos en una generación determinada.

Estoy acostumbrado a Netbeans Profiler. Realmente no puede hacer lo que está pidiendo, pero tiene una herramienta que puede darle ideas de lo que está pasando mal.

Ejecute la aplicación con Profiler, seleccione Memory, luego en Live Results tiene una columna Generations. No le dice la generación de cada objeto pero le da el número de Surviving Generations. Entonces, si el número es mayor que 1, es probable que esté en el espacio permanente (tal vez en el espacio de supervivientes), si el número siempre aumenta, tiene fugas de memoria.

0

No creo que haya ninguna utilidad que pueda informarle sobre el no de objetos en diferentes generaciones.

  1. Una forma es Puede usar jconsole que viene con jdk. Con la ayuda de jconsole puede conectarse a su aplicación y controlar todas las generaciones, aquí puede obtener algunas cifras que no estoy seguro.
  2. Otra forma es que puede tomar un volcado usando jmap y luego lo analiza usando la herramienta eclipse MAT.
  3. O puede ejecutar su aplicación con los argumentos siguientes JVM y en el registro que tenga la información acerca de GC

GC logging is enabled using JVM arguments; below are the arguments I use. (Note: the log file specified as file is reset each time the VM starts.

-verbose:gc -Xloggc:file

Creo que puede útil para usted.

1

La pista del elefante de la herramienta puede perfilar la creación del objeto y la muerte, elephantTrack. Con esto, puede averiguar qué tipo de objetos sobreviven más de lo esperado, y con el historial del método, es posible obtener objetos exactos.

Pero un gran montón significa un perfil muy largo y un archivo de perfil muy grande.

+0

Pero ... según el sitio web, no funciona para Java 1.7 y (supuestamente) versiones posteriores. –

Cuestiones relacionadas