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" 的线程是什么情况——它们完成了吗?因为我没有什么可以等待...
所以,我发现
- 数字 "Threads" 排除了每个已完成的线程 - 因此所有线程都 运行 或正在等待某事。
- 这也是这个数字如此摇摆不定的原因。
再次检查我的源代码后,我发现一些 ExecutorService 对象没有正确关闭,所以我更正了它并收到了下图(看起来更好!)
所以当其他人遇到类似问题时,我就是这样做的:
- 登录应用程序所在的机器运行
- 通过运行从进程中获取正确的PID
ps -aux | grep -i 'NAME'
(将 NAME 替换为应用程序的正确名称)
通过执行cat /proc/[PID]/status
得到running/waiting个线程数
使用 for x in {1..100000}; do echo $(date) - $(find /proc/[PID]/task -maxdepth 1 | wc -l); sleep 1; done >> thread_counter.csv
创建图形数据
我创建了一个总共有 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" 的线程是什么情况——它们完成了吗?因为我没有什么可以等待...
所以,我发现
- 数字 "Threads" 排除了每个已完成的线程 - 因此所有线程都 运行 或正在等待某事。
- 这也是这个数字如此摇摆不定的原因。
再次检查我的源代码后,我发现一些 ExecutorService 对象没有正确关闭,所以我更正了它并收到了下图(看起来更好!)
所以当其他人遇到类似问题时,我就是这样做的:
- 登录应用程序所在的机器运行
- 通过运行从进程中获取正确的PID
ps -aux | grep -i 'NAME'
(将 NAME 替换为应用程序的正确名称) 通过执行
cat /proc/[PID]/status
得到running/waiting个线程数
使用
for x in {1..100000}; do echo $(date) - $(find /proc/[PID]/task -maxdepth 1 | wc -l); sleep 1; done >> thread_counter.csv
创建图形数据