Explicación del archivo de salida de HPROF
La primera parte del archivo contiene datos de cabecera generales como, por ejemplo, una explicación de las opciones, el copyright y las declaraciones de limitación de responsabilidad. A continuación aparece un resumen de cada hebra.
Puede ver la salida después de utilizar HPROF con un programa simple, que aparece de la siguiente forma. Este programa de prueba crea y ejecuta dos hebras durante un breve período de tiempo. En la salida, puede ver que se han creado dos hebras denominadas apples
y luego oranges
después de la hebra main
generada por el sistema. Ambas hebras finalizan antes de la hebra de main
. Para cada hebra, se muestran su dirección, identificador, nombre y nombre de grupo de hebras. Puede ver el orden en el que se inician y finalizan las hebras.
THREAD START (obj=11199050, id = 1, name="Signal dispatcher", group="system")
THREAD START (obj=111a2120, id = 2, name="Reference Handler", group="system")
THREAD START (obj=111ad910, id = 3, name="Finalizer", group="system")
THREAD START (obj=8b87a0, id = 4, name="main", group="main")
THREAD END (id = 4)
THREAD START (obj=11262d18, id = 5, name="Thread-0", group="main")
THREAD START (obj=112e9250, id = 6, name="apples", group="main")
THREAD START (obj=112e9998, id = 7, name="oranges", group="main")
THREAD END (id = 6)
THREAD END (id = 7)
THREAD END (id = 5)
La sección de salida de la hebra contiene información normal sobre el rastreo de la pila. La profundidad de cada rastreo se puede establecer y cada rastreo tiene un ID único:
TRACE 5:
java/util/Locale.toLowerCase(Locale.java:1188)
java/util/Locale.convertOldISOCodes(Locale.java:1226)
java/util/Locale.<init>(Locale.java:273)
java/util/Locale.<clinit>(Locale.java:200)
Un rastreo contiene diversos marcos, y cada marco contiene el nombre de clase, nombre de método, nombre de archivo y número de línea. En el examen anterior, puede ver que el número de línea 1188 de Locale.java
(que está en el método toLowerCase) ha sido llamado desde la función convertOldISOCodes() de la misma clase. Estos rastreos son útiles a la hora de seguir la vía de acceso de ejecución del programa. Si establece la opción de supervisor, se produce un volcado de supervisor similar a este ejemplo:
MONITOR DUMP BEGIN
THREAD 8, trace 1, status: R
THREAD 4, trace 5, status: CW
THREAD 2, trace 6, status: CW
THREAD 1, trace 1, status: R
MONITOR java/lang/ref/Reference$Lock(811bd50) unowned
waiting to be notified: thread 2
MONITOR java/lang/ref/ReferenceQueue$Lock(8134710) unowned
waiting to be notified: thread 4
RAW MONITOR "_hprof_dump_lock"(0x806d7d0)
owner: thread 8, entry count: 1
RAW MONITOR "Monitor Cache lock"(0x8058c50)
owner: thread 8, entry count: 1
RAW MONITOR "Monitor Registry lock"(0x8058d10)
owner: thread 8, entry count: 1
RAW MONITOR "Thread queue lock"(0x8058bc8)
owner: thread 8, entry count: 1
MONITOR DUMP END
MONITOR TIME BEGIN (total = 0 ms) Thu Aug 29 16:41:59 2002
MONITOR TIME END
- R (Runnable): Ejecutable (la hebra puede ejecutarse cuando tenga oportunidad)
- S (Suspended): Suspendida (la hebra ha sido suspendida por otra hebra)
- CW (Condition Wait): Condición de espera (la hebra está esperando)
- MW (Monitor Wait): Espera de supervisor (el supervisor está esperando)
El Heapdump es la siguiente sección. Esta información contiene una lista de las diferentes áreas de memoria, y muestra cómo se asignan:
CLS 1123edb0 (name=java/lang/StringBuffer, trace=1318)
super 111504e8
constant[25] 8abd48
constant[32] 1123edb0
constant[33] 111504e8
constant[34] 8aad38
constant[115] 1118cdc8
CLS 111ecff8 (name=java/util/Locale, trace=1130)
super 111504e8
constant[2] 1117a5b0
constant[17] 1124d600
constant[24] 111fc338
constant[26] 8abd48
constant[30] 111fc2d0
constant[34] 111fc3a0
constant[59] 111ecff8
constant[74] 111504e8
constant[102] 1124d668
...
CLS 111504e8 (name=java/lang/Object, trace=1)
constant[18] 111504e8
CLS le notifica que se está asignando memoria para una clase. El número hexadecimal que lo sigue es la dirección a la que se asigna dicha memoria.
A continuación está el nombre de clase seguido de una referencia de rastreo. Utilice esta información como referencia cruzada de la salida de rastreo y vea cuándo se llama a la clase. Si hace referencia a ese rastreo en particular, puede obtener el número de línea de la instrucción que le llevó a la creación de este objeto. Las direcciones de las constantes de esta clase también aparecen y, en el ejemplo anterior, la dirección de la definición de clase de la superclase. Ambas clases son un hijo de la misma superclase (con la dirección 11504e8
). Si observa más la salida, podrá ver dicho nombre y definición de clase. Es la clase de objeto (una clase de la que se hereda cada clase). La JVM carga toda la jerarquía de superclases antes de utilizar una subclase. Por tanto, las definiciones de clase de todas las superclases siempre están presentes. También hay entradas para objetos (OB
J) y matrices (ARR
):
OBJ 111a9e78 (sz=60, trace=1, class=java/lang/Thread@8b0c38)
name 111afbf8
group 111af978
contextClassLoader 1128fa50
inheritedAccessControlContext 111aa2f0
threadLocals 111bea08
inheritableThreadLocals 111bea08
ARR 8bb978 (sz=4, trace=2, nelems=0, elem type=java/io/ObjectStreamField@8bac80)
Si establece la opción heap en sites o all, obtendrá una lista de cada área de almacenamiento asignada por su código. El parámetro all combina dump y sites. Esta lista está ordenada empezando por los sitios que asignan más memoria:
SITES BEGIN (ordered by live bytes) Tue Feb 06 10:54:46 2007
percent live alloc'ed stack class
rank self accum bytes objs bytes objs trace name
1 20.36% 20.36% 190060 16 190060 16 300000 byte[]
2 14.92% 35.28% 139260 1059 139260 1059 300000 char[]
3 5.27% 40.56% 49192 15 49192 15 300055 byte[]
4 5.26% 45.82% 49112 14 49112 14 300066 byte[]
5 4.32% 50.14% 40308 1226 40308 1226 300000 java.lang.String
6 1.62% 51.75% 15092 438 15092 438 300000 java.util.HashMap$Entry
7 0.79% 52.55% 7392 14 7392 14 300065 byte[]
8 0.47% 53.01% 4360 16 4360 16 300016 char[]
9 0.47% 53.48% 4352 34 4352 34 300032 char[]
10 0.43% 53.90% 3968 32 3968 32 300028 char[]
11 0.40% 54.30% 3716 8 3716 8 300000 java.util.HashMap$Entry[]
12 0.40% 54.70% 3708 11 3708 11 300000 int[]
13 0.31% 55.01% 2860 16 2860 16 300000 java.lang.Object[]
14 0.28% 55.29% 2644 65 2644 65 300000 java.util.Hashtable$Entry
15 0.28% 55.57% 2640 15 2640 15 300069 char[]
16 0.27% 55.84% 2476 17 2476 17 300000 java.util.Hashtable$Entry[]
17 0.25% 56.08% 2312 16 2312 16 300013 char[]
18 0.25% 56.33% 2312 16 2312 16 300015 char[]
19 0.24% 56.57% 2224 10 2224 10 300000 java.lang.Class
En este ejemplo, el rastreo 300055 asignó 5,27% de la memoria asignada total. Este porcentaje es igual a 49192 bytes.
La opción cpu le ofrece información de perfiles sobre el procesador. Si cpu está establecida en samples, la salida contendrá los resultados de muestreos periódicos realizados durante la ejecución del código. En cada muestreo, se registra la vía de acceso procesada y se produce un informe similar a:
CPU SAMPLES BEGIN (total = 714) Fri Aug 30 15:37:16 2002
rank self accum count trace method
1 76.28% 76.28% 501 77 MyThread2.bigMethod
2 6.92% 83.20% 47 75 MyThread2.smallMethod
...
CPU SAMPLES END
Puede ver que bigMethod() fue responsable del 76,28% del tiempo de ejecución del procesador y se ejecutó 501 veces cada 714 muestreos. Si utiliza los ID de rastreo, podrá ver la ruta exacta que llevó a que se llamase a este método.