自家製の Web アプリケーションをプロファイリングしているときに、非常に奇妙な (少なくとも私にとっては) 観察に出くわしました。
ほとんどすべての時間がクラスsocketRead0()
のメソッドに費やされます。SocketInputStream
私のアプリケーションはリクエストごとにリモート サービスとのネットワーキングを行うため、これは驚くべきことではありません。この方法ではウォールクロック時間の使用率が高いだけでなく、 CPU クロック時間も非常に高いのは奇妙なことです。なぜ CPU 時間が高いのか理解できません。なぜなら、アプリケーションがリモート サービスの応答を待っていると (実際にはそれほど速くはありません)、アプリケーション自体に何もすることがないからです。したがって、CPU 時間は明らかに低いはずです。
もう少し観察:
- サンプリング モードの VisualVM は、メソッド
SocketInputStream.socketRead0()
が最大 95% の時間 (ウォール クロック時間とCPU 時間の両方) を消費していることを示しています。 mpstat
(OS として Linux を使用) 約 90% のユーザー時間と ~1-3% のシステム時間 (残りはアイドル時間) を示します。- 専用サーバーにデプロイされたアプリケーション。
- リモート サービスも HTTP Web アプリケーションです。平均応答時間は約 100ms です。平均応答サイズは約 2Kb です。
- 私のアプリケーションはSpring
RestTemplate
を使用して、直接ではなくリモートサービスと対話しSocketInputStream
ます。
今のところ、私には 1 つの考えしかありません。おそらく、これは JVM でネイティブ メソッドを呼び出すことのオーバーヘッドです (SocketInputStream.socketRead0()
ネイティブです)。
どう思いますか?これには他の理由がありますか?