我有一个生产服务器,运行时显示大量分叉vmstat -f
。有什么建议可以帮助找出分叉来源的步骤吗?
vmstat -f 1
6650796 forks
编辑:
[~]$ ./forks.sh
Forks in last 2 seconds: 20
Forks in last 2 seconds: 40
Forks in last 2 seconds: 58
Forks in last 2 seconds: 9
Forks in last 2 seconds: 6
Forks in last 2 seconds: 28
Forks in last 2 seconds: 8
Forks in last 2 seconds: 10
Forks in last 2 seconds: 15
Forks in last 2 seconds: 9
答案1
根据手册页,它包括对 fork、vfork 或 clone 的所有调用。Java 使用这三个中的最后一个(clone)来实现其线程
因此,每次 Java 服务器创建新线程时,该值就会增加。
只要不出错,应该没问题。平均每秒您能看到多少个?
答案2
任何产生另一个进程但自身未终止的进程都算作一次 fork - 例如,在 shell 中执行的每个命令都算作一次 fork。自系统启动以来,fork 调用次数非常多是完全正常的。
答案3
首先要注意的是,运行不带两个时间参数的 vmstat 会显示自上次重启以来的累计值。您必须多次运行它才能获得“每秒 fork 数”数字,以查看它是否真的是一个很大的数字。类似这样的代码(显然可以将其制作成更友好的脚本):
g3 0 /home/jj33 ># while true
> do
> vmstat -f
> sleep 15
> done
278039 forks
278044 forks
278047 forks
278051 forks
因此,该系统在 3 个 15 秒间隔内执行了 5、3 和 4 次分叉,考虑到 *nix 机器上的每个进程调用都涉及一次分叉,这似乎不是一个很大的数字。
答案4
如果您怀疑某个进程(例如 JVM)是导致 fork 计数较高的原因(2/s 并不高也不是问题),您可以使用 strace/ltrace 查看其正在做什么。
具体来说,fork 也应该在使用 accton 命令的进程记帐(影响更大)中可见。但我认为它不包括用于启动线程的 clone()。
如果您进入 100 个克隆/秒的范围,那么您真的应该看看该应用程序。
顺便说一句:关于上面的评论(还不能评论):不,Tomcat 不会分叉,它只启动线程,但不是针对每个请求,它使用一个池。