測試在進行一次性能測試的時候發現並發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