java - interfaz - ¿Mejores formas de identificar objetos que no se recogen basura?
que es awt y swing en java (3)
Puedes probar JProfiler 10 días gratis. Con JProfiler resolverás este problema en unos minutos.
En una palabra
Tengo un programa que está usando gradualmente más y más memoria a lo largo del tiempo. Estoy usando jmap y jhat para intentar diagnosticarlo, pero todavía no estoy allí.
Fondo
El programa es un servidor de larga duración respaldado por un datastore hbase que proporciona un servicio de ahorro a un montón de otras cosas. Sin embargo, después de ejecutarse durante unos días, eventualmente llegará al límite de montón asignado, y se moverá de un lado a otro con casi todo el tiempo que se pase en la recolección de basura. Parece que las referencias se mantienen en una gran cantidad de datos en alguna parte
Lo que hice hasta ahora
Después de juguetear con jstat y jconsole, terminé tomando heapdumps con jmap del proceso en ejecución, y lo ejecuté a través de jhat, y los números simples no se suman a ningún lugar cerca de la utilización de la memoria.
jmap -F -dump:live,format=b,file=heap.dump 12765
jmap -F -dump:format=b,file=heap.all 12765
Algunas cosas de la parte superior del histograma
Class Instance Count Total Size
class [B 7493 228042570
class java.util.HashMap$Entry 2833152 79328256
class [Ljava.util.HashMap$Entry; 541 33647856
class [Ljava.lang.Object; 303698 29106440
class java.lang.Long 2851889 22815112
class org.apache.hadoop.hbase.KeyValue 303593 13358092
class org.apache.hadoop.hbase.client.Result 303592 9714944
class [I 14074 9146580
class java.util.LinkedList$Entry 303841 7292184
class [Lorg.apache.hadoop.hbase.KeyValue; 303592 7286208
class org.apache.hadoop.hbase.io.ImmutableBytesWritable 305097 4881552
class java.util.ArrayList 302633 4842128
class [Lorg.apache.hadoop.hbase.client.Result; 297 2433488
class [C 5391 320190
Si bien los totales aquí no se suman, en el momento en que se tomó el volcado del montón, el proceso utilizaba más de 1 gb de memoria.
El culpable aparente inmediato parece que estoy dejando las entradas HBase Result y KeyValue por todos lados. Tratando de rastrear las referencias, eventualmente golpeé
Object at 0x2aab091e46d0
instance of org.apache.hadoop.hbase.ipc.HBaseClient$Call@0x2aab091e46d0 (53 bytes)
Class:
class org.apache.hadoop.hbase.ipc.HBaseClient$Call
Instance data members:
done (Z) : true
error (L) : <null>
id (I) : 57316
param (L) : org.apache.hadoop.hbase.ipc.HBaseRPC$Invocation@0x2aab091e4678 (48 bytes)
this$0 (L) : org.apache.hadoop.hbase.ipc.HBaseClient@0x2aaabfb78f30 (86 bytes)
value (L) : org.apache.hadoop.hbase.io.HbaseObjectWritable@0x2aab092e31c0 (40 bytes)
References to this object:
Other Queries
Reference Chains from Rootset
Exclude weak refs
Include weak refs
Objects reachable from here
Se necesita ayuda:
No parece haber referencias a este objeto final HBaseCLient $ Call (ni a ninguno de los otros similares, cada uno de los cuales contiene un millar de valores clave con todos sus datos internos). ¿No debería estar recibiendo GCed? ¿Acabo de malinterpretar cómo funciona el gc o hasta qué punto jhat verificará las referencias? Si es así, ¿qué más puedo hacer para rastrear mi memoria "perdida"? ¿Qué otros pasos puedo seguir para rastrear esto?
Recomiendo primero probar JVisualVM, que se distribuye con el último JDK.
Además, si puede justificar el costo, he descubierto que JProfiler es una excelente herramienta a lo largo de los años.
Verifique este artículo de Java Memory Monitoring Enlace
Esto puede ayudarlo a vencer su problema http://java.sun.com/developer/technicalArticles/J2SE/monitoring/