Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在本机方法中,可运行线程可能不会占用CPU?_Java_Performance_Thread Dump - Fatal编程技术网

Java 在本机方法中,可运行线程可能不会占用CPU?

Java 在本机方法中,可运行线程可能不会占用CPU?,java,performance,thread-dump,Java,Performance,Thread Dump,在对大部分处于空闲状态的Tomcat服务器进行线程转储时,许多线程可能会显示为可运行状态,如下所示: "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

在对大部分处于空闲状态的Tomcat服务器进行线程转储时,许多线程可能会显示为可运行状态,如下所示:

"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-bio-8443-exec-21975”守护进程prio=10 tid=0x00007f6f6406c000 nid=0x222a可运行[0x00007f6f156ae000]
java.lang.Thread.State:可运行
位于java.net.SocketInputStream.socketRead0(本机方法)
位于java.net.SocketInputStream.read(SocketInputStream.java:129)
位于org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:516)
位于org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:501)
位于org.apache.coyote.http11.Http11Processor.setRequestLineReadTimeout(Http11Processor.java:173)
位于org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:924)
位于org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
位于org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
-锁定(org.apache.tomcat.util.net.SocketWrapper)
位于java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
运行(Thread.java:662)
我对源代码的解释是,该线程正在等待(超时)来自HTTP keepalive连接的更多数据。因此,即使线程是可运行的,它也不会消耗CPU

说:

处于可运行状态的线程正在Java虚拟机中执行,但它可能正在等待来自操作系统的其他资源,如处理器

因此,在本例中,其他资源将是I/O,而不是CPU

在其他问题中,答案如下:

我相信,当您使用Java本机方法时,堆栈跟踪将显示RUNNABLE,即使调用实际上在等待某个事件时被阻止。本质上,我认为Java无法知道本机方法实际在做什么,因此它将这些调用标记为可运行。我已经在socketRead0()和socketAccept()中看到了这一点,这两个函数通常都会阻塞

我得出了类似的结论,我想在这个专门问题中验证这种解释,即:

如果我想通过查看可运行线程来分析CPU消耗,我可能必须非常仔细地查看本机方法中的线程的源代码来排除它们?

P>这一点是,它不像查看线程的状态那么简单,而是必须深入到源代码并开始猜测特定的本地方法可能在做什么(或者甚至查看它的C或C++源代码)。有一个到目前为止遇到的本地方法的小概要可能是有用的

如果我想通过查看可运行线程来分析CPU消耗,我可能必须通过非常仔细地查看其源代码来排除本机方法中的线程

你可能想把他们排除在外。但总的来说,你不能。本机方法可以在阻塞或消耗大量CPU的两种状态之间切换。即使您详细检查了代码,也无法仅从线程堆栈转储中判断代码处于何种状态

(如果你能掌握本机电脑,你也许能……但即使如此,也需要付出巨大的努力才能实现。)



当然,标准库中有许多本机方法几乎不消耗CPU,您当然可以在分析中使用它们。然而,还有其他标准本机库可能表现出“混合模式”行为;e、 g.本机ZIP库以及AWT、SWT等中使用的一些本机库。

我想您已经回答了自己的问题。标题并非完全正确:本机方法消耗CPU。但是,正如您所解释的,JVM不知道本机方法在做什么,因此状态“RUNNABLE”是不相关的,例如线程可以等待IO(因此不等待CPU)。显然,您可以使用操作系统监视工具,但我不会得到一个漂亮的Java堆栈跟踪。。。