java 应用程序中的线程处理

Thread handling in a java application

我创建了一个总共有 11 个预定作业的服务 运行。其中 3 个由 cron 作业安排(其中 2 个每 15 分钟一次,最后一个每分钟一次)。这三个任务仅用于监控服务(检查 JVM 使用的 ehCache 和 RAM)。所有其他计划任务都用 'fixedDelay' 属性注释 - 因此只有在最后一个任务完成并且经过 x 时间后才应启动新线程,对吗?

通过 http://ask.xmodulo.com/number-of-threads-process-linux.html 我发现,我可以通过执行

检查每个进程的线程数
cat /proc/PID/status

结果如下

Name:   jsvc
Umask:  0022
State:  S (sleeping)
Tgid:   17263
Ngid:   0
Pid:    17263
PPid:   17260
TracerPid:      0
Uid:    99      99      99      99
Gid:    99      99      99      99
FDSize: 8192
Groups: 99 11332 16600 34691 50780 52730 52823 53043 54173
NStgid: 17263
NSpid:  17263
NSpgid: 17260
NSsid:  17260
VmPeak: 35247540 kB
VmSize: 35232620 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:   5679220 kB
VmRSS:   5663344 kB
RssAnon:         5660016 kB
RssFile:            3328 kB
RssShmem:              0 kB
VmData: 32106616 kB
VmStk:      1012 kB
VmExe:        44 kB
VmLib:     16648 kB
VmPTE:     50908 kB
VmPMD:       128 kB
VmSwap:        0 kB
HugetlbPages:          0 kB
Threads:        19922
SigQ:   0/64039
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000004
SigIgn: 0000000000000000
SigCgt: 2000000181005ecf
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
Seccomp:        0
Speculation_Store_Bypass:       vulnerable
Cpus_allowed:   7fff
Cpus_allowed_list:      0-14
Mems_allowed:  00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list:      0
voluntary_ctxt_switches:        5986
nonvoluntary_ctxt_switches:     26

所以我的第一个问题是:'Threads' 号码告诉我什么?是否有 19922 个线程,包括已结束的线程,或者这只是当前活动的线程?

我还想知道为什么所有这些线程当前都处于 SLEEPING 状态...

我制作了一个图表 (#1),它显示了这个进程的当前线程数,我可以看到这个数字不仅在增加。

为什么这个数字如此波动? 线程结束后是否应该删除线程的子目录? 状态为 "SLEEPING" 的线程是什么情况——它们完成了吗?因为我没有什么可以等待...

所以,我发现

  1. 数字 "Threads" 排除了每个已完成的线程 - 因此所有线程都 运行 或正在等待某事。
  2. 这也是这个数字如此摇摆不定的原因。

再次检查我的源代码后,我发现一些 ExecutorService 对象没有正确关闭,所以我更正了它并收到了下图(看起来更好!)

所以当其他人遇到类似问题时,我就是这样做的:

  1. 登录应用程序所在的机器运行
  2. 通过运行从进程中获取正确的PID ps -aux | grep -i 'NAME'(将 NAME 替换为应用程序的正确名称)
  3. 通过执行cat /proc/[PID]/status

  4. 得到running/waiting个线程数
  5. 使用 for x in {1..100000}; do echo $(date) - $(find /proc/[PID]/task -maxdepth 1 | wc -l); sleep 1; done >> thread_counter.csv

  6. 创建图形数据