熟悉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