熟悉Java的童鞋,应该对OOM比较熟悉。该类问题,通常都比较棘手。由于形成此类问题的缘由有不少。今天就分享一个很是有意思的案例。(说实话。这个问题,我也是前两天才遇到的。花了很多时间来分析。以为很是有意思,记录在此。大神勿喷!)java
重启应用时,调试到给MQ发消息时。有以下错误:apache
Exception in thread "Thread-4" java.lang.OutOfMemoryError: unable to create new native thread at java.lang.Thread.start0(Native Method) at java.lang.Thread.start(Thread.java:717) at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:957) at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1378) at org.apache.activemq.thread.PooledTaskRunner.wakeup(PooledTaskRunner.java:81) at org.apache.activemq.transport.failover.FailoverTransport.reconnect(FailoverTransport.java:757) at org.apache.activemq.transport.failover.FailoverTransport.start(FailoverTransport.java:344) at org.apache.activemq.transport.TransportFilter.start(TransportFilter.java:58) at org.apache.activemq.transport.TransportFilter.start(TransportFilter.java:58)
一开始,觉得是系统磁盘,或者内存占满致使。经过top
命令查看系统信息。均属于正常范围。正在尝试寻找其余方案的同时。在SSH中输入命令是。出现如下错误:tomcat
$ bash: fork: Resource temporarily unavailable
出现上述问题后:很是明显的提示来资源不足致使。性能优化
经分析:是因为当前系统使用的线程数大于ulimit中的max_user_processes的数量致使。bash
上面说到了,与系统(Linux)中的ulimit参数有关。ulimit 是用来限制系统资源的。
其中包括:微信
max memory size (最大内存大小)。性能
open files(打开文件数)。优化
max user processes(最大用户进程数)
等等。spa
系统性能优化经常会优化此参数。.net
(有兴趣的童鞋能够自行了解更多)
1. 显示open files
$ ulimit -n 65535
其中 ulimit -n 显示的结果为: open files的数值。
2. 显示当前用户的最大进程数
$ ulimit -u 60000
其中ulimit -u 显示的结果为: max_user_processes额值。
2. 显示ulimit 全部属性
$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 127399 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 65535 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 60000 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
其中:
open files 表示打开文件的最大数。
max user processes 当前用户打开能打开的最大进程数。
其中open files 属性, 能够在/etc/security/limits.conf
文件中修改。在文件末尾添加。以下所示代码:
* soft nofile 65535 * hard nofile 65535
其中:
nofile 表示 open files
nproc 对应的属性为: max_user_processes
其中 65535 为演示数字。请按照环境的实际状况进行调整。
其中 max_user_processes属性,能够在/etc/security/limits.d/90-nproc.conf
路径下进行修改。
修改以下:
* soft nproc 60000 root soft nproc unlimited
须要注意的是:
max_user_processes中最大的值为: 60000。
若是设置超过60000,则默认为最大值。例如: 设置 655535,则会为60000。
执行上述步骤后。退出当前会话。从新链接便可生效!在修改以前链接的会话,须要从新链接,才能看到新的配置。
1. 查看当前系统使用的进程数。
咱们可使用: ps aux|wc -l
或者ps -ef|wc -l
命令来查看当前正在使用的进程数。
以下所示:
$ ps aux|wc -l 309
有时经过ps aux|wc -l
命令查看获得的数据少于max_user_processes
的值。
也出现:
$ bash: fork: Resource temporarily unavailable`
这是由于一个进程中能够包含多个线程致使。
2. 查看指定进程数中的线程数。
当咱们知道了的进程ID(PID)后,
也能够经过以下方法查看当前进程中有多少个线程:
命令:
$ cat /proc/<pid>/status
案例以下:
andy@andyqian:/java$ cat /proc/11723/status Name: java State: S (sleeping) Tgid: 11723 Ngid: 0 Pid: 11723 PPid: 2434 TracerPid: 0 Uid: 1000 1000 1000 1000 Gid: 1000 1000 1000 1000 FDSize: 128 Groups: 4 24 27 30 46 108 124 1000 Threads: 28 SigQ: 0/47456 Seccomp: 0 Cpus_allowed: ff Cpus_allowed_list: 0-7 Mems_allowed: 00000000,00000001 Mems_allowed_list: 0 voluntary_ctxt_switches: 88 nonvoluntary_ctxt_switches: 3
其中:
Threads:28 就表示该进程中,一个有28个线程。
因为篇幅缘由,以上删除了部分信息。
3. 如何查看应用的进程 可能有童鞋不知道如何查看应用的进程数,这里给个简单的案例:
例如查看一个名命为tomcat01
的tomcat。咱们能够经过以下命令查看:
ps -aux|grep tomcat01
以下所示:
andy@andyqian:/java$ ps -aux|grep tomcat01 andy 11723 0.5 1.0 6484560 127292 pts/1
其中: 11723 对应的就是tomcat01的进程ID。
扫码关注,一块儿进步
我的博客: http://www.andyqian.com