最近,我在Java应用程序服务器安装上进行了分析/调整,以识别瓶颈并修复它们。 在此过程中(调整),最常见的操作是在系统加载时检索许多线程转储。 请记住,重载(在某些情况下)可能会产生副作用,可能会导致我们得出错误的结论。 因此,“控制”负载比实际重负载更可取。
当系统处于加载状态时,您会注意到许多Java线程处于RUNNABLE状态,但它们并未真正运行。 他们正在等待“ 某物 ”。
导致线程即使处于RUNNABLE状态也要等待的最常见原因如下:
- CPU资源不足 :当运行的线程多于虚拟CPU时,上下文切换,内核,OS作业和系统的其他进程会有延迟是正常的。
- RAM不足 :如果您的RAM不足,则您的系统将使用swap,这总是一个问题。
- I / O :当线程处于read()或write()调用中并等待数据写入或读取时,该线程处于RUNNABLE状态,但实际上并未运行。
- 网络慢 :这与#3有关,因为网络慢得多,它将导致与网络操作有关的“正在运行”线程的较长延迟。
- 流程优先级 :流程可以具有不同的优先级。 如果JVM进程以低优先级运行,则其他进程将在CPU中更频繁地运行。 您可以使用top (GNU Linux), prstat (Solaris), 任务管理器 (Windows)之类的工具来执行此操作。
- 垃圾收集(GC) :运行GC时,JVM的所有线程(GC线程除外)在某些地方(世界停止)都处于冻结状态。 在这些时候,GC正在删除无用的引用对象,因此释放了堆的可用内存大小(但仅限于此)。 我们必须使用这样的策略(例如CMS或G1),以最小化停靠点的频率和持续时间。
完全由JVM引起的唯一原因是最后一个(GC活动)。 所有其他方面主要取决于操作系统和硬件。 因此,我们还必须始终监视系统(操作系统和硬件),而不仅仅是JVM。
您必须记住,Java不使用/遵循其自己的线程模型。 此外,当前的JVM(热点)使用本机OS线程,并且线程调度由底层OS实现。
参考:处于Java集成和源博客的优点的 JCG合作伙伴 Adrianos Dadis并没有真正运行处于RUNNABLE状态的Java Thread 。
翻译自: https://www.javacodegeeks.com/2012/08/java-thread-at-runnable-state-is-not.html