本文來自于HeapDump性能社區(qū)! !有性能問題,上HeapDump性能社區(qū)!
正文:
Java 應用程序本質上是多線程的。這意味著用 Java 編寫的程序可以同時(表面上)做幾件事。例如——即使在只有一個處理器的機器上——當您將內容從一個窗口拖到另一個窗口時,在后臺播放的電影不會因為您一次執(zhí)行多項操作而停止。
考慮線程的一種方法是將它們視為可以向其提交任務以執(zhí)行的工人。如果您只有一名工人,他或她當時只能執(zhí)行一項任務。但是,當您擁有十幾個工人時,他們可以同時執(zhí)行您的多個命令。
現(xiàn)在,與物理世界中的工人一樣,JVM 中的線程需要一些肘部空間來執(zhí)行他們被召喚來處理的工作。當線程多于內存空間時,我們已經為問題奠定了基礎:

消息java.lang.OutOfMemoryError: Unable to create new native thread意味著Java 應用程序已達到它可以啟動的線程數(shù)限制。
1,什么原因造成的?
您有機會遇到java.lang.OutOfMemoryError: Unable to create new native thread每當 JVM 向操作系統(tǒng)請求新線程時。每當?shù)讓硬僮飨到y(tǒng)無法分配新的本機線程時,就會拋出此 OutOfMemoryError。本機線程的確切限制非常依賴于平臺,因此我們建議通過運行類似于以下示例的測試來找出這些限制。但是,一般情況下,導致java.lang.OutOfMemoryError: Unable to create new native thread 的情況會經歷以下幾個階段:
- 運行在 JVM 中的應用程序請求一個新的 Java 線程
- JVM 本機代碼將創(chuàng)建新本機線程的請求代理到操作系統(tǒng)
- 操作系統(tǒng)嘗試創(chuàng)建一個新的本地線程,該線程需要為線程分配內存
- 操作系統(tǒng)將拒絕本機內存分配,因為 32 位 Java 進程大小已耗盡其內存地址空間 - 例如 (2-4) GB 進程大小限制已達到 - 或操作系統(tǒng)的虛擬內存已完全耗盡
- 該java.lang.OutOfMemoryError:無法創(chuàng)建新的本地線程引發(fā)錯誤。
2,舉個例子
以下示例在循環(huán)中創(chuàng)建并啟動新線程。運行代碼時,會快速達到操作系統(tǒng)限制并顯示java.lang.OutOfMemoryError: Unable to create new native thread消息。
while(true){
new Thread(new Runnable(){
public void run() {
try {
Thread.sleep(10000000);
} catch(InterruptedException e) { }
}
}).start();
}
確切的本機線程限制取決于平臺,例如在 Windows、Linux 和 Mac OS X 上的測試表明:
- 64 位 Mac OS X 10.9,Java 1.7.0_45 – JVM 在 #2031 線程創(chuàng)建后終止
- 64 位 Ubuntu Linux,Java 1.7.0_45 – JVM 在 #31893 線程創(chuàng)建后終止
- 64 位 Windows 7、Java 1.7.0_45 – 由于操作系統(tǒng)使用的線程模型不同,此錯誤似乎不會在此特定平臺上引發(fā)。在線程 #250,000 上,即使交換文件已增長到 10GB 并且應用程序面臨極端的性能問題,該進程仍處于活動狀態(tài)。
因此,請確保通過調用一個小測試了解自己的限制,并找出何時會觸發(fā)java.lang.OutOfMemoryError: Unable to create new native thread
3,解決方案
有時,您可以通過增加操作系統(tǒng)級別的限制來繞過無法創(chuàng)建新的本機線程問題。例如,如果您限制了 JVM 可以在用戶空間中產生的進程數(shù),您應該檢查并可能增加限制:
[root@dev ~]# ulimit -a
核心文件大?。▔K,-c)0
--- 為簡潔起見 ---
最大用戶進程 (-u) 1800
通常情況下,OutOfMemoryError 對新本地線程的限制表明存在編程錯誤。當您的應用程序產生數(shù)千個線程時,很可能出現(xiàn)了嚴重錯誤——沒有多少應用程序可以從如此大量的線程中受益。
解決問題的一種方法是開始進行線程轉儲以了解情況。你通常會花幾天的時間來做這件事。我們的建議是將Plumbr連接到您的應用程序,以找出導致問題的原因以及如何在幾分鐘內解決它。
Java OOM系列專題:
第一篇:Java OOM 原理篇 : 什么是 Java OOM
第二篇:Java OOM 基礎篇:常見的OutOfMemoryError 場景一:Java heap space 堆溢出問題詳解
第三篇:Java OOM 基礎篇:常見的OutOfMemoryError 場景二 : GC overhead limit exceeded 問題詳解
第四篇:Java OOM 基礎篇:常見的OutOfMemoryError 場景三: PermGen space 永久空間問題詳解
第五篇:Java OOM 基礎篇:常見的OutOfMemoryError 場景四: Permgen size 元空間問題詳解
第六篇:Java OOM 實戰(zhàn)篇:應用故障之Java heap space 堆溢出實戰(zhàn)