曾常常遇到此問題,一般想法就是改動配置啟動參數,想方設法增大參數,覺得這樣能夠避免內存溢出。但效果基本上還是會出錯。我在網上找到了一篇文章解決此問題 點擊打開鏈接 主要觀點為
這個異常問題本質原因是我們創建了太多的線程,而能創建的線程數是有限制的,導致了異常的發生。能創建的線程數的詳細計算公式例如以下: (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的使用情況在剛啟動時比出錯時值要高一點,啟動后回歸正常。而且服務能夠正常啟動了。
綜合上面的情況,並在簡單的實踐后,我覺得引用文章中的理論應該是有道理的,所下面次再遇到此異常,最好還是試試將有關配置參數減少,沒准會解決這個問題。