程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 記一次tomcat線程創建異常調優:unable to create new native thread,tomcat調優

記一次tomcat線程創建異常調優:unable to create new native thread,tomcat調優

編輯:JAVA綜合教程

記一次tomcat線程創建異常調優:unable to create new native thread,tomcat調優


測試在進行一次性能測試的時候發現並發300個請求時出現了下面的異常:

HTTP Status 500 - Handler processing failed; nested exception is java.lang.OutOfMemoryError: unable to create new native thread

看到這個異常有點發慌,畢竟並發程序寫的少,突然來這麼一個確實有點找不著背。但不管怎麼樣還是先搜索一下是啥原因吧。

這個錯誤是因為無法再創建新線程導致的,原因可能是沒有更多的空間用於創建線程,還有一個公式用來計算:

(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads

這其中各個參數的意思是:
MaxProcessMemory:進程最大尋址空間。
JVMMMEMORY:jvm的內存空間(堆+永久區)-Xmx大小 (應該是實際分配大小)
ReservedOsMemory:操作系統預留內存
ThreadStackSize:-Xss大小

懶得寫了,找一篇參考:https://my.oschina.net/xinxingegeya/blog/744462

於是我查看一下liunx系統的參數情況:

[root@RHEL63temp ~]# 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) 63628
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
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) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

其中的max user processes只有1024個,心想著這事情可能問題不在於創建的限制,而是為什麼要創建這麼多線程?畢竟只有300個並發,tomcat最多也就300個線程用於處理請求吧?

於是想了想程序代碼的問題,還是要從代碼上去查找原因。於是臨時開始研究了一下JVisualVM這個監控工具,在服務器上做了做配置,反正網上有教程。因為我使用的是Tomcat,所以直接就監控Tomcat吧,在catalina.sh中增加一些參數:

JAVA_OPTS="-server -Xmx384m -Xms128m -XX:PermSize=128M -XX:MaxPermSize=256m"
	-Dcom.sun.management.jmxremote.port=9998 
	-Dcom.sun.management.jmxremote.ssl=false 
	-Dcom.sun.management.jmxremote.authenticate=false 
	-Djava.rmi.server.hostname=192.168.49.199"

這樣就可以使用JVisualVM通過JMX方式監控了。連接上後再進行測試問題原因找到了。

線程產生這麼大主要是兩塊:
1、tomcat的本身需要支持並發的線程
2、smack產生的大量線程,而且連續壓測會發現smack的線程出現不釋放的情況

這裡的關鍵是smack的使用,因為系統實現了一個功能就是通過網頁發起ajax請求,然後在服務端模擬即時通過用戶發送消息。因為並發300個請求,導致每個請求都要創建smack的連接,而smack是用於客戶端開發的庫,啟動後會創建3個左右的線程用於連接和處理服務器的通訊。這就導致同時會產生300*3的線程,所以並發時會所線程創建數用滿。

既然問題原因找到了,所以這裡的問題可能還是smack的使用問題,畢竟smack是個客戶端庫,不太適合於這種服務端的場景。

解決方法是使用其他方式代替smack發消息,這樣只需要創建少量的線程就可以滿足要求,而且處理速度大大提升。

 

注:此文章為原創,歡迎轉載,請在文章頁面明顯位置給出此文鏈接! 若您覺得這篇文章還不錯請點擊下右下角的推薦,非常感謝! http://www.cnblogs.com/5207

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved