解決 - java.lang.OutOfMemoryError: unable to create new native thread


曾常常遇到此問題,一般想法就是改動配置啟動參數,想方設法增大參數,覺得這樣能夠避免內存溢出。但效果基本上還是會出錯。我在網上找到了一篇文章解決此問題 點擊打開鏈接 主要觀點為

這個異常問題本質原因是我們創建了太多的線程,而能創建的線程數是有限制的,導致了異常的發生。能創建的線程數的詳細計算公式例如以下:
(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads
MaxProcessMemory 指的是一個進程的最大內存
JVMMemory         JVM內存
ReservedOsMemory  保留的操作系統內存
ThreadStackSize      線程棧的大小

在java語言里, 當你創建一個線程的時候,虛擬機會在JVM內存創建一個Thread對象同一時候創建一個操作系統線程,而這個系統線程的內存用的不是JVMMemory,而是系統中剩下
的內存(MaxProcessMemory - JVMMemory - ReservedOsMemory)。 

由公式得出結論:你給JVM內存越多,那么你能創建的線程越少,越easy發生java.lang.OutOfMemoryError: unable to create new native thread。 

解決這個問題:
1, 假設程序中有bug,導致創建大量不須要的線程或者線程沒有及時回收,那么必須解決這個bug,改動參數是不能解決這個問題的。
2, 假設程序確實須要大量的線程,現有的設置不能達到要求,那么能夠通過改動MaxProcessMemory,JVMMemory,ThreadStackSize這三個因素,來添加能創建的線程數:
a, MaxProcessMemory 使用64位操作系統
b, JVMMemory   降低JVMMemory的分配
c, ThreadStackSize  減小單個線程的棧大小

這個觀點讓我開始也非常不解,但細致查看了一下出錯日志

# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 2334888 bytes for Chunk::new
# An error report file with more information is saved as:
# D:\xxx_err_pid1904.log
在查看具體的pid日志,則驚喜的發現其給出的解決方法與上面講到的理論同樣

#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 2355528 bytes for Chunk::new
# Possible reasons:
#   The system is out of physical RAM or swap space
#   In 32 bit mode, the process size limit was hit
# Possible solutions:
#   Reduce memory load on the system
#   Increase physical memory or swap space
#   Check if swap backing store is full
#   Use 64 bit Java on a 64 bit OS
#   <span style="color:#FF0000;">Decrease Java heap size (-Xmx/-Xms)</span>
#   <span style="color:#FF0000;">Decrease number of Java threads</span>
#   <span style="color:#FF0000;">Decrease Java thread stack sizes (-Xss)</span>
#   Set larger code cache with -XX:ReservedCodeCacheSize=
# This output file may be truncated or incomplete.
#
#  Out of Memory Error (allocation.cpp:328), pid=4308, tid=6720
#
# JRE version: 7.0_25-b16
# Java VM: Java HotSpot(TM) Server VM (23.25-b01 mixed mode windows-x86 )
# Failed to write core dump. Call to MiniDumpWriteDump() failed
#
注意上面標紅色處
於是將tomcat服務啟動參數都改小了一半,變為例如以下參數

-Xms256M
-Xmx512M
-Xss1M

再啟動服務,並馬上觀察任務管理中tomcat進程具體,內存使用情況較出錯時內存使用上漲的最大值小了,並逐漸回落到一個比較低的值。而CPU的使用情況在剛啟動時比出錯時值要高一點,啟動后回歸正常。而且服務能夠正常啟動了。

綜合上面的情況,並在簡單的實踐后,我覺得引用文章中的理論應該是有道理的,所下面次再遇到此異常,最好還是試試將有關配置參數減少,沒准會解決這個問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM