スケーラビリティの問題(スレッド/コアの観点から)を検出するために、実行中の並列Javaアプリケーションのすべての同期呼び出しを一覧表示する方法を探しています。私の理解では、同期されたブロックが入力されるたびに、マシンはキャッシュを同期する必要があります。これは、同期領域に入って実行中のタスクがブロックされていない場合でも、実行中のすべてのCPUに影響します(メモリ帯域幅など、いくつかの方法で)。
より高いレベルで並列化された大規模なアプリケーションがあります。つまり、並列で実行される複雑なタスクがあります。並列化は、すべてのコアに負荷がかかっており、ブロックされたスレッドがないという用語で機能します。それでも、パフォーマンスはコアに合わせてスケーリングされていません。これにはいくつかの理由が考えられます。私が興味を持っている特定の考えられる理由は、同期呼び出しがたくさんある場合です(たとえば、同期ブロックへの入力、ロックの使用など)。
コード内のどの場所(実際に実行されるか)にそのような同期呼び出しがあり、各同期が実際に実行される頻度を調べたいと思います。参照されるライブラリは多数あるため、同期されたキーワードなどで通常のコード検索を使用することはできません。これは、実行されていないコードを多数検索し、誤検知を多く発生させるためです。完璧な解決策は、実行されたすべての同期場所と呼び出しの数を一覧表示するプロファイラーを用意することです。ただし、私が試したプロファイラーでは、メソッド呼び出しのみがカウントされます。したがって、ここでの問題は、実際に関連するすべてのメソッドを見つけることです。
または、エントリポイント(メインメソッド)によって参照されている同期場所を見つけることができれば、それも役立ちます。つまり、コードを再帰的に調べて、参照されているすべてのメソッド、クラスなどでそのような同期を確認します。この場合、通常のプロファイラーを使用して、後で周波数を見つけることができます。
より大きなプロジェクトのために上記のタスクをアーカイブできるツールまたはワークフローはありますか?
事前にTHXでお答えします。
同期ブロックへの出入りは、このブロックで競合がない限り、かなり安価な操作です。競合しない場合synchronized
は、アトミックCASであるか、UseBiasedLocking
最適化が成功した場合はほとんど何もしません。Instrumentation APIを使用して同期プロファイラーを実行することは可能に見えますが、これはあまり意味がありません。
マルチスレッドアプリケーションの問題は、競合する同期です。JVMには、ロックの競合を監視するための内部カウンターがいくつかあります(この質問を参照)。または、JVMTIイベントを使用して、競合するすべてのロックを追跡する簡単なアドホックツールを作成することもできます。
ただし、ロックだけでなく、競合が発生する可能性があります。非ブロッキングアルゴリズムでさえ、共有リソースをめぐる競争に苦しむ可能性があります。これは、そのようなスケーラビリティの問題の良い例です。したがって、パフォーマンスの問題を見つけるのに通常はより便利なので、CPUプロファイラーから始める方が良いという@PeterLawreyに同意します。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加