2016-09-13 3 views
0

ObjectHeap.iterateObjectsOfKlass(SAの助けを借りて)を呼び出すと、特定のクラスに属するすべてのオブジェクトを取得できました。結果はまさに私が予想したものですが、パフォーマンスはそうではありません。HotSpot ServiceabilityエージェントのiterateObjectsOfKlass()が遅すぎる

ターゲットVMが中断されている間に、結果が出るまでに800秒以上かかりました。ターゲットVMヒープは約2GBです。私はiterateObjectsOfKlassiterateExactに電話することを知っています。

私の質問です:これらのメソッドは、1クラスのオブジェクトを取得するためにのみヒープ全体を繰り返し/トラバースしますか?私は、1つのクラスで10秒以内に結果が返ってくるはずだと私は期待していますので、私はがっかりです。

+1

しかし、それは起源の形態(特にServiceability Agentに精通していない人たち)ではあまり明確ではありませんでした。 – apangin

+0

もちろん、あらゆる種類のオブジェクトを見つけるためにヒープ全体をスキャンする必要があります。フィルターのタイプはその事実に影響を与えません。どのようにそれが動作すると思いますか? – Holger

+0

私はヒープ全体がスキャンされることを期待していませんでした。私は、クラスが指定されて以来、iterateObjectsOfKlassがそのオブジェクトの検索において外科手術になると考えていました。 - マティアス。おかげで@Holger –

答えて

4

HotSpot Serviceability Agentは本当に強力なテクノロジーですが、実際は非常に遅いです。私はそれがthis answerの仕組みについて説明しました。

JVMには、特定のクラスのすべてのインスタンスをすばやく見つける方法がありません。したがって、はい、ヒープ全体をスキャンする必要があります。さらに、外部プロセスのメモリを読み込むために、SAは1ワードのデータごとにptraceシステムコールを使用します。だからこそ遅いです。

あなたはヒープ速くスキャンするいくつかのオプションがあります。

  1. が外国プロセスのコアダンプを作成し、コアダンプに対するSAのツールを実行します。これは中断されたプロセスのメモリを読み出すよりはるかに高速です。 related questionを参照してください。
  2. Dynamic Attach mechanismを使用して実行中のプロセスにJVMTIエージェントを注入します。エージェントはIterateOverInstancesOfClass機能を使用してローカルJVMのヒープをスキャンできます。これはSAと比べて劇的に速くなります。これは、同じプロセス内でシステムコールや何もせずに読み取るだけなので、SAよりも劇的に高速です。私は2GBのヒープのためにほんの数秒かかると信じています。
+1

あなたの良い答えをありがとう! @apangin –