首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Tomcat「unable to create new native thread」實戰排查:從 300 並發到 Smack 線程洩漏

     編輯:Java 綜合教學

故障現場

性能測試並發 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:進程最大尋址空間(32 位約 2-4GB)
  • JVMMemory:堆 + 永久區(-Xmx 設定值)
  • ReservedOsMemory:系統預留內存
  • ThreadStackSize:-Xss 設定值(默認 1MB)

系統層面排查

[root@RHEL63temp ~]# ulimit -a
max user processes (-u) 1024    # 用戶進程/線程上限
stack size (kbytes, -s) 10240   # 線程棧大小 10MB

max user processes = 1024 遠大於 300,系統限制非瓶頸。

代碼層面定位:JVisualVM 監控

開啟 JMX 遠程監控

# 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"

監控發現:線程來源雙峰

  1. Tomcat 處理請求的工作線程(~300)
  2. Smack 庫創建的線程(~900,且不釋放)

根因分析:Smack 庫誤用

  • 業務需求:Web 發起 AJAX → 服務端模擬用戶發送即時消息
  • 實現方式:每個請求創建一個 Smack 連接
  • Smack 設計定位:客戶端庫,啟動即創建 3 條線程(連接、心跳、消息處理)
  • 300 並發 × 3 線程 = 900 線程,加上 Tomcat 自身線程,迅速耗盡系統線程配額

解決方案

  • 替換 Smack:改用服務端適合的消息推送方案(如服務端 XMPP 庫、HTTP 長輪詢、WebSocket)
  • 效果:線程數大幅下降,吞吐量顯著提升

核心教訓

客戶端庫不可直接用於高並發服務端場景。引入第三方庫前,必須評估其線程模型、資源佔用及釋放機制。

原文鏈接:https://www.cnblogs.com/5207

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved