Лучшие способы определения объектов, которые не собираются сборщиком мусора?

Вкратце

У меня есть программа, которая со временем постепенно использует все больше и больше памяти. Я использую jmap и jhat, чтобы попытаться диагностировать это, но все еще не совсем там.

Предпосылки

Программа представляет собой долго работающий сервер, поддерживаемый хранилищем данных hbase, предоставляющий бережливые услуги для множества других вещей. Однако по прошествии нескольких дней он в конечном итоге достигнет выделенного лимита кучи и будет метаться взад и вперед, почти все время затрачивая на сборку мусора. Казалось бы, ссылки где-то хранятся в большом количестве данных

То, что я делал до сих пор

После того, как я возился с jstat и jconsole, я закончил тем, что взял кучи с jmap запущенного процесса и прогнал его через jhat, а простые числа не складываются ни в какое сравнение с использованием памяти

jmap -F -dump: live, format = b, file = heap.dump 12765

jmap -F -dump: format = b , file = heap.all 12765

Кое-что не в верхней части гистограммы

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

Хотя итоги здесь не складываются, в момент создания дампа кучи процесс использовал более 1 ГБ памяти.

Непосредственный очевидный виновник, кажется, я оставляю записи HBase Result и KeyValue повсюду. Пытаясь отследить ссылки, я в конце концов наткнулся на

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

Требуется помощь:

Похоже, что нет никаких ссылок на этот последний объект HBaseCLient $ Call (или любой другой подобный ему, каждый из которых содержит около тысячи ключевых значений с все их внутренние данные). Разве это не должно быть GCed? Я просто не понимаю, как работает gc или насколько jhat проверяет ссылки? Если да, то что еще я могу сделать, чтобы отследить мою «недостающую» память? Какие еще шаги я могу предпринять, чтобы отследить это?

8
задан juhanic 21 December 2010 в 02:39
поделиться