3

ほとんどがアイドル状態の Tomcat サーバーのスレッドダンプを取得すると、多くのスレッドが次のように RUNNABLE 状態で表示される場合があります。

"http-bio-8443-exec-21975" daemon prio=10 tid=0x00007f6f6406c000 nid=0x222a runnable [0x00007f6f156ae000]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(SocketInputStream.java:129)
        at org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:516)
        at org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:501)
        at org.apache.coyote.http11.Http11Processor.setRequestLineReadTimeout(Http11Processor.java:173)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:924)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
        - locked <0x00000007cadcd3f8> (a org.apache.tomcat.util.net.SocketWrapper)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
        at java.lang.Thread.run(Thread.java:662)

ソースコードの私の解釈は、このスレッドが HTTP キープアライブ接続からの追加データを (タイムアウトで) 待っているということです。そのため、スレッドが RUNNABLE であっても、CPU を消費しません。

Thread.State RUNNABLE javadocは次のように述べています。

実行可能状態のスレッドは Java 仮想マシンで実行されていますが、プロセッサなどのオペレーティング システムからの他のリソースを待機している可能性があります。

したがって、この場合、他のリソースは CPU ではなく I/O になります。

他の質問Java socketRead0 Issueで、ジェフは次のように答えています。

Java ネイティブ メソッドを使用している場合、呼び出しが実際に何らかのイベントを待ってブロックされていても、スタック トレースには RUNNABLE と表示されると思います。本質的に、ネイティブ メソッドが実際に何を行っているかを Java が知る方法はないと思います。そのため、Java はこれらの呼び出しに RUNNABLE のフラグを立てます。私は socketRead0() と socketAccept() でこれを見てきました - どちらも通常ブロックします。

私も同様の結論に達したので、この専用の質問でこの解釈を検証したいと思います。

RUNNABLE Threads を調べて CPU 消費を分析したい場合、ネイティブ メソッドのスレッドのソースコードを詳しく調べて除外する必要があるかもしれません。

要点は、スレッドの状態だけを見るほど簡単ではなく、ソースコードを掘り下げて、特定のネイティブ メソッドが何をしているのかを推測する必要があることです (または、その C または C++ ソースコードを調べることさえあります)。

4

2 に答える 2

1

It's OK to Ask and Answer Your Own Questions の行では、私の答えは「はい」です。これは必要かもしれません。

于 2014-10-20T09:39:58.937 に答える
0

RUNNABLE Threads を調べて CPU 消費を分析したい場合、ネイティブ メソッドのスレッドのソースコードを詳しく調べて除外する必要があるかもしれません。

それらを除外したい場合があります。しかし、一般的にはできません。ネイティブ メソッドは、ブロックされているか大量の CPU を消費している 2 つの状態を交互に繰り返す可能性があります。コードを詳しく調べても、スレッドのスタックダンプだけではどのような状態だったのかわかりません。

(ネイティブ PC を手に入れることができれば、できるかもしれませんが、それでさえも実装するには大変な努力が必要です。)


もちろん、標準ライブラリには、ほとんど CPU を消費しないネイティブ メソッドが多数あります。これを分析に利用できることは間違いありません。ただし、「混合モード」の動作を示す可能性が高い他の標準ネイティブ ライブラリがあります。たとえば、ネイティブ ZIP ライブラリと、AWT や SWT などで使用されるネイティブ ライブラリの一部です。

于 2014-10-20T09:55:27.320 に答える