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虚拟机没法为新线程申请内存。写的程序没有控制好内存。