Linux /proc线程数与ThreadMXBean.getThreadCount()数值差异原因咨询
问题:ThreadMXBean返回的线程数远低于/proc命令统计值
在CentOS系统上运行Java程序通过ThreadMXBean获取线程数时,执行cat /proc/<pid>/status|grep Threads得到的线程数为17,但程序输出的线程数仅为5。实际场景中也遇到Prometheus JMX Exporter展示的线程数偏低,而Graphite通过Linux命令获取的数值更高的情况。
程序代码如下:
import java.lang.management.*; public class threadmxbean { public static void main(String[] args) { // Get the ThreadMXBean instance ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); // Print the number of threads currently running System.out.println("Number of threads-getThreadCount(): " + threadMXBean.getThreadCount()); System.out.println("Number of threads-getDaemonThreadCount(): " + threadMXBean.getDaemonThreadCount()); System.out.println("Number of threads-getTotalStartedThreadCount(): " + threadMXBean.getTotalStartedThreadCount()); try{Thread.sleep(500000);}catch(InterruptedException e){System.out.println(e);} } }
程序输出:
Number of threads-getThreadCount(): 5 Number of threads-getDaemonThreadCount(): 4 Number of threads-getTotalStartedThreadCount(): 5
原因解析
统计范围本质不同
/proc/<pid>/status里的Threads字段是Linux内核层面统计的进程所有线程总数,包含JVM运行时创建的所有Native线程、Java线程,以及第三方Native库创建的线程。而ThreadMXBean仅统计Java层面可感知的线程——也就是通过java.lang.Thread类创建,或者JVM暴露给Java层管理的线程,Native线程不在它的统计范围内。JVM内部隐藏的Native线程
JVM启动后会自动创建多个内部Native线程,这些线程不会被ThreadMXBean计数,但会被Linux内核算进进程线程数:- GC相关线程:比如Parallel GC的Worker线程、CMS的标记/清理线程
- JIT编译线程:C2编译器的后台编译线程
- 系统信号处理线程(Signal Dispatcher)
- JVM监控线程(Attach Listener)
这些线程是JVM运行的必要组件,但不属于Java线程范畴,这是两者数值差异的主要来源。
监控工具的实现逻辑差异
Prometheus JMX Exporter依赖JMX接口(基于ThreadMXBean),只能获取Java线程数;而Graphite直接调用Linux命令读取内核统计的进程线程数据,包含所有类型线程,因此数值更高。
内容的提问来源于stack exchange,提问作者J Jena
相关产品推荐
相关产品推荐

