11

奇妙な JVM パフォーマンスの問題が発生しています。

大きくてやや不透明な GUI コンポーネント (Actuate Formula 1 スプレッドシート) があります。

すべてをイベ​​ント ディスパッチ スレッドから初期化すると (当然のことですが)、コードの実行がかなり遅くなることがわかります (マウスをドラッグしてセルを選択すると、顕著な遅延が発生します)。

最初にメイン ランチャー スレッドで初期化してから、EDT で使用を開始すると、はるかに高速に実行されます。

プロファイラーを使用してパフォーマンスが遅い理由を調べると、常に時間がかかっているメソッド呼び出しは次のとおりです。

  • java.lang.Object.getClass()
  • java.lang.reflect.Array.newInstance(Class, int)
  • java.lang.Class.getComponentType()
  • java.lang.Thread.currentThread()

Windows 7 で 64 ビットの Sun Hotspot JVM (JDK に付属するもの) を使用しています。

上記の方法が通常よりも大幅に遅くなる理由を知っている人はいますか?

クラスがロードされる順序と関係があるのではないかと考えています....それは合理的な理論ですか?これらのメソッド呼び出しに時間がかかる理由を診断できる他の方法を知っている人はいますか?

プロファイラーからの 2 つのスクリーンショットを添付しました。どちらの場合も、プロファイラーの実行中にマウスをスプレッドシートのセルの周りにドラッグするだけでした。つまり、GUI コンポーネントを更新するだけで、他には何もしていません。

最初のものは、「releaseLock()」というメソッドに多くの時間を費やしています。なんらかの理由で、「getComponentType()」に通常よりもかなり長い時間がかかっているため、これに時間がかかっています。

リリースロック

2 つ目は、「ハック」を行って「releaseLock()」のコストを削除した後ですが、getClass() と currentThread() が通常よりもはるかに長い時間がかかるため、「getLock()」に多くの時間を費やしているだけです。 :

getLock

しかし、重要なことは、コードを初期化する順序を変更するだけで、このコードの実行にそれほど時間がかからないことです (プロファイラーにもまったく表示されません)。

getLock() を最適化したとしても、アプリケーションの実行はさらに遅くなります。問題は、getClass() などのメソッドに時間がかかりすぎることです。これを補う方法はありません - getClass() があまりにも多くの場所で呼び出されます!

プロファイラーが実行されていなくても、パフォーマンスの違いは顕著です。

また、このコードは変更できないことも覚えておいてください。これは外部コンポーネントです。課題は、ある状況と他の状況でコードの実行が非常に遅い理由を説明することです。

4

1 に答える 1

1

負荷がかかった状態で、複数の混合 (Java + ネイティブ)アプリケーションのjstack -mスレッド ダンプを取得することを試みることができます。

これはおそらく、 のフードの下で何が起こっているかについてのヒントを与えるでしょうObject.getClass()

プロファイラーが答えでない場合、他にどのような選択肢がありますか?も参照してください。.

また、JVM が GC で時間を費やしたときにスレッド ダンプがどのように見えるかをご覧ください。原因 通常の JVM スレッド ダンプは、セーフポイントでのみ発生するため、常に完全に正確であるとは限りません。

于 2013-01-10T19:05:43.543 に答える