Java 线程转储 CPU 还是只是 IO 等待?

标签 java performance jvm java-threads thread-dump

我复制了一个可疑的线程转储。 我在调用 java.net.SocketInputStream.socketRead0() 时看到 173 个线程处于 IN_NATIVE 状态 在同一个调用中有 30 个线程处于 BLOCKED 状态。
我认为 BLOCKED 状态不会消耗 CPU,但它们正在等待 IO。

处于 IN_NATIVE 状态的线程呢?他们消耗CPU吗? 任何想法,为什么我看到同一个调用 socketRead0() 的不同线程状态?

173 threads
Thread 40283 - threadId:Thread 40283 - state:IN_NATIVE
stackTrace:
java.net.SocketInputStream.socketRead0(java.io.FileDescriptor, byte[], int, int, int) @bci=0 (Compiled frame; information may be imprecise)
java.net.SocketInputStream.read(byte[], int, int, int) @bci=87, line=152 (Compiled frame)
java.net.SocketInputStream.read(byte[], int, int) @bci=11, line=122 (Compiled frame)
com.sun.mail.util.TraceInputStream.read(byte[], int, int) @bci=7, line=110 (Compiled frame)
java.io.BufferedInputStream.fill() @bci=175, line=235 (Compiled frame)
java.io.BufferedInputStream.read() @bci=12, line=254 (Compiled frame)
com.sun.mail.util.LineInputStream.readLine() @bci=33, line=88 (Compiled frame)
com.sun.mail.smtp.SMTPTransport.readServerResponse() @bci=43, line=1589 (Compiled frame)
com.sun.mail.smtp.SMTPTransport.openServer(java.lang.String, int) @bci=117, line=1369 (Compiled frame)
com.sun.mail.smtp.SMTPTransport.protocolConnect(java.lang.String, int, java.lang.String, java.lang.String) @bci=270, line=412 (Compiled frame)
javax.mail.Service.connect(java.lang.String, int, java.lang.String, java.lang.String) @bci=380, line=288 (Compiled frame)
com.healthies.push.injectors.mailsenders.DefaultMailSender.sendMessage(com.healthies.push.messages.EmailMessage, javax.mail.internet.MimeMessage) @bci=28, line=63 (Compiled frame)
com.healthies.push.injectors.SMTPMessageInjector.sendMessage(com.healthies.push.injectors.mailsenders.MailSender, com.healthies.push.messages.EmailMessage, javax.mail.internet.MimeMessage) @bci=55, line=140 (Compiled frame)
com.healthies.push.injectors.SMTPMessageInjector.inject(com.healthies.push.messages.EmailMessage) @bci=210, line=117 (Compiled frame)
com.healthies.push.injectors.SMTPMessageInjector.inject(com.healthies.push.messages.Message) @bci=5, line=35 (Compiled frame)
com.healthies.push.injectors.EmailInjectorPool$1.run() @bci=85, line=40 (Compiled frame)
java.util.concurrent.Executors$RunnableAdapter.call() @bci=4, line=471 (Compiled frame)
java.util.concurrent.FutureTask.run() @bci=42, line=262 (Compiled frame)
java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) @bci=95, line=1145 (Compiled frame)
java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=5, line=615 (Interpreted frame)
java.lang.Thread.run() @bci=11, line=745 (Interpreted frame)
--------------------------------------------------------------------
30 threads 
Thread 40276 - threadId:Thread 40276 - state:BLOCKED
stackTrace:
java.net.SocketInputStream.socketRead0(java.io.FileDescriptor, byte[], int, int, int) @bci=0 (Compiled frame; information may be imprecise)
java.net.SocketInputStream.read(byte[], int, int, int) @bci=87, line=152 (Compiled frame)
java.net.SocketInputStream.read(byte[], int, int) @bci=11, line=122 (Compiled frame)
com.sun.mail.util.TraceInputStream.read(byte[], int, int) @bci=7, line=110 (Compiled frame)
java.io.BufferedInputStream.fill() @bci=175, line=235 (Compiled frame)
java.io.BufferedInputStream.read() @bci=12, line=254 (Compiled frame)
com.sun.mail.util.LineInputStream.readLine() @bci=33, line=88 (Compiled frame)
com.sun.mail.smtp.SMTPTransport.readServerResponse() @bci=43, line=1589 (Compiled frame)
com.sun.mail.smtp.SMTPTransport.issueSendCommand(java.lang.String, int) @bci=6, line=1494 (Compiled frame)
com.sun.mail.smtp.SMTPTransport.finishData() @bci=34, line=1321 (Compiled frame)
com.sun.mail.smtp.SMTPTransport.sendMessage(javax.mail.Message, javax.mail.Address[]) @bci=281, line=637 (Compiled frame)
com.healthies.push.injectors.mailsenders.DefaultMailSender.sendMessage(com.healthies.push.messages.EmailMessage, javax.mail.internet.MimeMessage) @bci=37, line=64 (Compiled frame)
com.healthies.push.injectors.SMTPMessageInjector.sendMessage(com.healthies.push.injectors.mailsenders.MailSender, com.healthies.push.messages.EmailMessage, javax.mail.internet.MimeMessage) @bci=55, line=140 (Compiled frame)
com.healthies.push.injectors.SMTPMessageInjector.inject(com.healthies.push.messages.EmailMessage) @bci=210, line=117 (Compiled frame)
com.healthies.push.injectors.SMTPMessageInjector.inject(com.healthies.push.messages.Message) @bci=5, line=35 (Compiled frame)
com.healthies.push.injectors.EmailInjectorPool$1.run() @bci=85, line=40 (Compiled frame)
java.util.concurrent.Executors$RunnableAdapter.call() @bci=4, line=471 (Compiled frame)
java.util.concurrent.FutureTask.run() @bci=42, line=262 (Compiled frame)
java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) @bci=95, line=1145 (Compiled frame)
java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=5, line=615 (Interpreted frame)
java.lang.Thread.run() @bci=11, line=745 (Interpreted frame)

最佳答案

通常您永远不会看到线程在BLOCKED 状态下执行非同步本地方法。但是此转储是在强制模式 (jstack -F) 下获得的,即 works differently .

JVM 似乎请求了一个 safepoint operation .所有运行 Java 代码的线程都必须在安全点停止,但 native 方法可能仍会运行。每当 native 方法返回时,它都会检查安全点操作是否正在进行,如果是,则阻塞当前线程,直到 VM 操作完成。

所以,在你的情况下

  • 处于BLOCKED 状态的线程已经完成 native 调用,并在方法返回时等待安全点操作结束;
  • 处于 IN_NATIVE 状态的线程仍在执行 native 调用,该调用可能在套接字读取时被阻塞。

JVM 无法区分被系统调用阻塞的 native 方法与实际消耗 CPU 的 native 方法 - 在这两种情况下,它都会显示一个处于 IN_NATIVE 状态的线程。您无法从线程转储中得出这些线程是否繁忙的结论。

为了查看本地方法是否消耗 CPU,您将需要一个实用程序,如 topperfnative code aware profiler .

关于Java 线程转储 CPU 还是只是 IO 等待?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45380752/

相关文章:

java - 如何将 Eclipse 插件公开为 Web 服务?

java - 重用 StringBuffer

android - 没有语言运行时的基于 JVM 的语言

java - XMLOutputStream、修复命名空间和没有命名空间的属性

java - MemoryCacheImageOutputStream 到 BufferedImage

performance - 在express中使用nodejs可以采取哪些措施来提高jade模板渲染性能

java - Java 匹配外括号太慢

java - 我在哪里可以找到有关 Sun 的 JVM 内部工作原理的信息?

java - 无法识别的选项 : -MaxMetaspaceSize=256m

java局部变量不可用