一台 java 服务器可以跑多少个线程?

一台 java 服务器能跑多少个线程?这个问题来自一次线上报警如下图,超过了我们的配置阈值。

京东自研 UMP 监控分析

打出 jstack 文件,通过 IBM Thread and Monitor Dump Analyzer for Java 工具查看如下:

IBM Thread and Monitor Dump Analyzer for Java

共计 1661 个线程,和监控数据得出的吻合。但这个数量应该是大了,我们都知道线程多了,就会有线程切换,带来性能开销。

当时就想到一台 java 服务器到底可以跑多少个线程呢?跟什么有关系?现整理如下。

每个线程都有一个线程栈空间通过 -Xss 设置,查了一下我们服务器的关于 jvm 内存的配置

-Xms4096m

-Xmx4096m

-XX:MaxPermSize=1024m

只有这三个,并没有 -Xss 和 -XX:ThreadStackSize 的配置,因此是走的默认值。几种 JVM 的默认栈大小

可以通过如下命令打印输出默认值的大小, 命令:jinfo -flag ThreadStackSize ;例如

[root@host-192-168-202-229 ~]#jinfo -flag ThreadStackSize 1807

-XX:ThreadStackSize=1024

不考虑系统限制,可以通过如下公式计算,得出最大线程数量

线程数量 =(机器本身可用内存 -JVM 分配的堆内存)/Xss 的值 ,比如我们的容器本身大小是 8G, 堆大小是 4096M, 走 -Xss 默认值,可以得出 最大线程数量:4096 个。

根据计算公式,得出如下结论:

结论 1:jvm 堆越大,系统创建的线程数量越小。

结论 2:当 -Xss 的值越小,可生成线程数量越多。

我们知道操作系统分配给每个进程的内存大小是有限制的,比如 32 位的 Windows 是 2G。因此操作系统对一个进程下的线程数量是有限制的,不能无限的增多。经验值:3000-5000 左右(我没有验证)。

刚才说的是不考虑系统限制的情况,那如果考虑系统限制呢,主要跟以下几个参数有关系

/proc/sys/kernel/pid_max 增大,线程数量增大,pid_max 有最高值,超过之后不再改变,而且 32,64 位也不一样

/proc/sys/kernel/thread-max 系统可以生成最大线程数量

max_user_process(ulimit -u)centos 系统上才有,没有具体研究

/proc/sys/vm/max_map_count 增大,数量增多

线程是非常宝贵的资源,我们要严格控制线程的数量,象上面我们的截图情况,显然线程数量过多。这个是跟我们自己配置了 fixed 大小的线程池有关系。京东有自己的 rpc 框架 jsf,里面可以针对每个服务端口设置线程大小。