JAVA虛擬機起步OutOfMemory問題解決記錄。java
問題: JAVA虛擬機報錯linux
# java.lang.OutOfMemoryError: requested 32756 bytes for ChunkPool::allocate. Out of swap space?
#
# Internal Error (allocation.cpp:117), pid=26666, tid=2409851824
# Error: ChunkPool::allocateweb
解決辦法:數據結構
平衡每一個線程須要的內存存儲器的堆棧大小,在程序內部控制線程總數量。多線程
理論:app
JVM線程堆棧webapp
應用程序中的每一個線程都須要內存來存儲器堆棧(用於在調用函數時持有局部變量並維護狀態的內存區域)。每一個 Java 線程都須要堆棧空間來運行。異步
根據實現的不一樣,Java 線程能夠分爲本機線程和 Java 堆棧。除了堆棧空間,每一個線程還須要爲線程本地存儲(thread-local storage)和內部數據結構提供一些本機內存。jsp
JVM堆棧大小函數
-Xss 128k:設置每一個線程的堆棧大小。JDK5.0之後每一個線程堆 棧大小爲1M,之前每一個線程堆棧大小爲256K。更具應用的線程所需內存大小進行調整。
在相同物理內存下,減少這個值能生成更多的線程。可是操做系統對一 個進程內的線程數仍是有限制的,不能無限生成,經驗值在3000~5000左右。
JVM heap與JVM私有內存、JVM線程堆棧大小間的關係及平衡。
線程棧的大小是個雙刃劍,若是設置太小,可能會出現棧溢出,特別是在該線程內有遞歸、大的循環時時出現溢出的可能性更大,若是該值設置過大,就有影響到建立棧的數量,若是是多線程的應用,就會出現內存溢出的錯誤.
經驗:
JAVA開大量線程須要注意的地方有,一個是unlimit設置能夠保證操做系統開啓的文件數量,另外一個就是須要考慮物理內存大小,最後要控制好線程總數量的上限。
案例:
JAVA程序在實現大量Socket鏈接代理過程當中,入口是經過異步SocketServer接口數據,開啓的accept和reader可控,出口須要一個鏈接開啓一個目標Socket(每一個Socket對應一個線程)。
一般一臺機器開啓的線程數值爲3000-5000個。我的感受是跟物理內存有關,若是是4G的物理內存,每一個線程默認開銷1M空間,5000個線程會所有暫用物理內存,JAVA虛擬機在開啓新線程是就會出現 java.lang.OutOfMemoryError: requested 32756 bytes for ChunkPool::allocate. Out of swap space?
基於此案例,首先想到的是經過優化程序下降線程的數量,而後經過調整虛擬機參數下降線程佔用內存數量。
附:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# java.lang.OutOfMemoryError: requested 32756 bytes for ChunkPool::allocate. Out of swap space?
#
# Internal Error (allocation.cpp:117), pid=26666, tid=2409851824
# Error: ChunkPool::allocate
#
# JRE version: 6.0_17-b04
# Java VM: Java HotSpot(TM) Server VM (14.3-b01 mixed mode linux-x86 )
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
在處理此問題過程當中,有的文章說是須要更換jdk版本,有的說是32bit和64bit的問題。
我的來看,問題的關鍵是java虛擬機沒法爲新線程申請內存。寫的程序沒有控制好內存。