8

手短に

時間の経過とともにメモリを徐々に使用しているプログラムがあります。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 GB を超えるメモリを使用していました。

すぐに明らかな犯人は、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 オブジェクトへの参照はないようです (または、それぞれがすべての内部データを含む 1000 ほどのキー値を保持する、同様の他のオブジェクトのいずれか)。GCされるべきではありませんか?gc がどのように機能するか、または jhat が参照を検証する範囲を誤解しているだけですか? もしそうなら、「失われた」記憶を追跡するためにさらに何ができますか? これを追跡するために他にどのような手順を実行できますか?

4

3 に答える 3

3

この Java メモリ監視の記事 リンクを確認してください

これは、問題を解決するのに役立ちます http://java.sun.com/developer/technicalArticles/J2SE/monitoring/

于 2010-12-21T02:54:55.437 に答える
1

JProfiler は 10 日間無料でお試しいただけます。JProfiler を使用すると、この問題を数分で解決できます。

于 2010-12-21T08:29:23.867 に答える
0

最初に、最新の JDK で配布される JVisualVM を試すことをお勧めします。

また、コストを正当化できるのであれば、長年にわたって JProfiler が優れたツールであることがわかりました。

于 2010-12-21T02:47:13.503 に答える