典型设置:
• java -Xmx3550m -Xms3550m -Xmn2g -Xss128k
-Xmx3550m:设置JVM最大可用内存为3550M。
-Xms3550m:设置JVM促使内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-Xmn2g:设置年轻代大小为2G。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
-Xss128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
• java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0
-XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5
-XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6
-XX:MaxPermSize=16m:设置持久代大小为16m。
-XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。
为了解决tomcat在进行大并发请求时,出现内存溢出的问题,请修改tomcat的内存大小,其中分为以下两种方式:
一、使用 catalina.bat 等命令行方式运行的 tomcat
查看系统是否能支持所填最大内存命令:java -Xmx1024m -version,当所填值不合法时,执行该命令将报错
1、修改 tomcat\bin\Catalina.bat 文件
windows环境下:
在166行左右
rem Execute Java with the applicable properties ”以下每行
%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
在 %DEBUG_OPTS% 后面添加-Xms256m -Xmx512m
linux环境下:
打开在Tomcat的安装目录的bin文件的catalina.sh文件,进入编辑状态.
在注释后面加上如下脚本:
JAVA_OPTS='-Xms512m -Xmx1024m'
JAVA_OPTS="$JAVA_OPTS -server -XX:PermSize=64M -XX:MaxPermSize=256m"
其中 JAVA_OPTS='-Xms512m -Xmx1024m' 是设置Tomcat使用的内存的大小.
-XX:PermSize=64M -XX:MaxPermSize=256m 指定类空间(用于加载类)的内存大小
保存后,重新以命令行的方式运行 tomcat ,即可,然后通过最后面介绍的如何观察tomcat现有内存情况的方法进行查看是否已经变更成功。
二、使用 系统中的 “服务”,或者开始菜单的可执行程序运行的tomcat
1、关闭 现在正在运行的tomcat
2.1 [注意]
[高版本tomcat配置方法]
如果是tomcat 5.5 或者是 5.0.28 之后的版本,在 Java 选项卡中,下方,会有
Inital memory Pool:
Maximum memory Pool:
Thread stack size:
三个输入框,在这里即可不用做上面的操作,直接配置内存大小,只需要设置
Inital memory Pool 为 256
Maximum memory Pool 为 512
点击确定后,重启tomcat 生效
如果您是低版本的tomcat,发现没有上面那几个录入框,请看下面的操作步骤
[低版本tomcat配置方法]
在开始菜单中,找到“Apache Tomcat 5.0”,并选择“Configure Tomcat”,在弹出的对话框窗口中,切换到 Java VM 选项卡,并在 Java Options 输入框的最前面输入
-Xms256m -Xmx512m
即输入框中的内容会像下面的代码(与自己的环境有所区别)
-Xms256m -Xmx512m
-Dcatalina.home="C:\tomcat5"
-Djava.endorsed.dirs="C:\tomcat5\common\endorsed"
-Xrs
设置完后,点击“确定”,并重启tomcat即可。
三、查看现有tomcat的内存大小情况
1、启动tomcat
2、访问 ,并输入您在安装tomcat时输入的用户与口令,如 admin ,密码 admin(密码是您在tomcat安装时输入的)
注:添加用户,修改conf/tomcat-users.xml
3、进入了Server Status页面,可以在JVM表格中看到
Free memory: 241.80 MB Total memory: 254.06 MB Max memory: 508.06 MB
上面的文字即代表了,当前空闲内存、当前总内存、最大可使用内存三个数据。
确定了最大内存足够大时,tomcat即可正常运转
最后总结下内存设置中常用的几个参数
(1)-Xms,jvm启动时,初始分配的堆/栈内存
(2)-Xmx,JVM最大允许分配的堆/栈内存,按需分配
(3)-Xss,设定每个线程的堆栈大小
(4)-XX:PermSize,JVM初始分配的非堆内存
(5)-XX:MaxPermSize,JVM最大允许分配的非堆内存,按需分配
举例:
-Xms256m -Xms512m -XX:PermSize=64m -XX:MaxPermSize=128m
本文简明概要地说明了java程序的占用内存构成
对象(Objects)
类(Classes)
线程(Theads)
本地数据结构(Native data structures)
本地代码(Native code)
每个因素对内存占用的影响又会随着应用程序、运行环境和系统的不同而变化,那怎样计算总的内存占用量?是的,想得到一个准确的数字不是那么容易,因为你很难控制本地(Native)部分。你能控制的部分只有堆大小:-Xmx,类占用的内存:-XX:MaxPermSize,还有线程栈:-Xss控制每个线程占用的内存。注意当把栈大小设置的太小时会导StackOverflow异常、程序出错。所以,计算公式为:
(-Xmx)+(-XX:MaxPermSize)+线程数*(-Xss)+其它内存
其它内存部分取决于本地代码占用的内存,如NIO、Socket缓冲区、JNI等。它一般大约是JVM内存的5%左右。所以假设我们有下面的JVM参数和100个线程:
-Xmx1024m-XX:MaxPermSize=256m-Xss512k
那么JVM进程至少会占用内存数量为:1024m+256m+100*512k+(0.05*1330m)=1396.5m
我一般使用(1.5*堆最大值)来作为一个近似值表示一个Tomcat进程会需要的最小内存,如果你有需要增加MaxPermSize到256M以上的应用这个值可以更大些。
以下配置主要针对分代垃圾回收算法而言。
堆大小设置
年轻代的设置很关键
JVM中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制。32位系统下,一般限制在1.5G~2G;64为操作系统对内存无限制。在Windows Server 2003 系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m。
典型设置:
java -Xmx3550m -Xms3550m -Xmn2g –Xss128k
-Xmx3550m:设置JVM最大可用内存为3550M。
-Xms3550m:设置JVM促使内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-Xmn2g:设置年轻代大小为2G。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
-Xss128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
原文地址:http://blog.csdn.net/ithomer/article/details/9936743
一、堆内存相关配置
设置堆初始值
指令1:-Xms2g
指令2:-XX:InitialHeapSize=2048m
设置堆区最大值
指令1:`-Xmx2g`
指令2: -XX:MaxHeapSize=2048m
缩小堆内存的时机
-XX:MaxHeapFreeRatio=70//堆内存使用率大于70时扩张堆内存,xms=xmx时该参数无效,默认值70
扩张堆内存的时机
-XX:MinHeapFreeRatio=40//堆内存使用率小于40时缩减堆内存,xms=xmx时该参数无效,默认值40
新生代内存配置
指令1:-Xmn512m
指令2:-XX:MaxNewSize=512m
2个survivor区和Eden区大小比率
指令:-XX:SurvivorRatio=6 //S区和Eden区占新生代比率为1:6,两个S区2:6
新生代和老年代的占比
-XX:NewRatio=4 //表示新生代:老年代 = 1:4 即老年代占整个堆的4/5;默认值=2
二、方法区内存配置常用参数
初始化的Metaspace大小,
-XX:MetaspaceSize :
Metaspace最大值
-XX:MaxMetaspaceSize
三、线程栈内存配置常用参数
每个线程栈最大值
指令1:-Xss256k
指令2:-XX:ThreadStackSize=256k
注意:
栈设置太大,会导致线程创建减少。
栈设置小,会导致深入不够,深度的递归会导致栈溢出。
建议栈深度设置在3000-5000
四、配置垃圾收集器
Serial垃圾收集器(新生代)
开启:-XX:+UseSerialGC
关闭:-XX:-UseSerialGC
//新生代使用Serial 老年代则使用SerialOld
ParNew垃圾收集器(新生代)
开启 -XX:+UseParNewGC
关闭 -XX:-UseParNewGC
//新生代使用功能ParNew 老年代则使用功能CMS
Parallel Scavenge收集器(新生代)
开启 -XX:+UseParallelOldGC
关闭 -XX:-UseParallelOldGC
//新生代使用功能Parallel Scavenge 老年代将会使用Parallel Old收集器
ParallelOl垃圾收集器(老年代)
开启 -XX:+UseParallelGC
关闭 -XX:-UseParallelGC
//新生代使用功能Parallel Scavenge 老年代将会使用Parallel Old收集器
CMS垃圾收集器(老年代)
开启 -XX:+UseConcMarkSweepGC
关闭 -XX:-UseConcMarkSweepGC
G1垃圾收集器
开启 -XX:+UseG1GC
关闭 -XX:-UseG1GC
五、GC策略配置
GC并行执行线程数
-XX:ParallelGCThreads=16
新生代可容纳的最大对象
-XX:PretenureSizeThreshold=1000000 //大于此值的对象直接会分配到老年代,设置为0则没有限制。 //避免在Eden区和Survivor区发生大量的内存复制,该参数只对Serial和ParNew收集器有效,Parallel Scavenge并不认识该参数
进入老年代的GC年龄
进入老年代最小的GC年龄
-XX:InitialTenuringThreshol=7 //年轻代对象转换为老年代对象最小年龄值,默认值7,对象在坚持过一次Minor GC之后,年龄就加1,每个对象在坚持过一次Minor GC之后,年龄就增加1
进入老年代最大的GC年龄
-XX:MaxTenuringThreshold=15 //年轻代对象转换为老年代对象最大年龄值,默认值15
六、GC日志信息配置
配置GC文件路径
-Xloggc:/data/gclog/gc.log//固定路径名称生成 -Xloggc:/home/GCEASY/gc-%t.log //根据时间生成
滚动生成日志
日志文件达到一定大小后,生成另一个文件。须配置Xloggc
开启 -XX:+UseGCLogFileRotation
关闭 -XX:-UseGCLogFileRotation
-XX:NumberOfGCLogFiles=4 //滚动GC日志文件数,默认0,不滚动 -XX:GCLogFileSize=100k //GC文件滚动大小,需配置UseGCLogFileRotation,设置为0表示仅通过jcmd命令触发
-Xmx Java Heap最大值,默认值为物理内存的1/4,最佳设值应该视物理内存大小及计算机内其他内存开销而定;
-Xms Java Heap初始值,Server端JVM最好将-Xms和-Xmx设为相同值,开发测试机JVM可以保留默认值;
-Xmn Java Heap Young区大小,不熟悉最好保留默认值; -Xss 每个线程的Stack大小,不熟悉最好保留默认值;
2
2. 如何分配JVM内存设置:
(1)当在命令提示符下启动并使用JVM时(只对当前运行的类Test生效): java -Xmx128m -Xms64m -Xmn32m -Xss16m Test (2)当在集成开发环境下(如eclipse)启动并使用JVM时:
a. 在eclipse根目录下打开eclipse.ini,默认内容为(这里设置的是运行当前开发工具的JVM内存分配): -vmargs -Xms40m -Xmx256m
-vmargs表示以下为虚拟机设置参数,可修改其中的参数值,也可添加-Xmn,-Xss,另外,eclipse.ini内还可以设置非堆内存,如:-XX:PermSize=56m,-XX:MaxPermSize=128m.
此处设置的参数值可以通过以下配置在开发工具的状态栏显示: 在eclipse根目录下创建文件options,文件内容为:org.eclipse.ui/perf/showHeapStatus=true
修改eclipse根目录下的eclipse.ini文件,在开头处添加如下内容: -debug options -vm javaw.exe
重新启动eclipse,就可以看到下方状态条多了JVM信息.
b. 打开eclipse-窗口-首选项-Java-已安装的JRE(对在当前开发环境中运行的java程序皆生效)
编辑当前使用的JRE,在缺省VM参数中输入:-Xmx128m -Xms64m -Xmn32m -Xss16m
c. 打开eclipse-运行-运行-Java应用程序(只对所设置的java类生效) 选定需设置内存分配的类-自变量,在VM自变量中输入:-Xmx128m -Xms64m
选定需设置内存分配的类-自变量,在VM自变量中输入:-Xmx128m -Xms64m -Xmn32m -Xss16m
注:如果在同一开发环境中同时进行了b和c设置,则b设置生效,c设置无效,如:
开发环境的设置为:-Xmx256m,而类Test的设置为:-Xmx128m -Xms64m,则运行Test时生效的设置为: -Xmx256m -Xms64m
(3)当在服务器环境下(如Tomcat)启动并使用JVM时(对当前服务器环境下所以Java程序生效): a. 设置环境变量: 变量名:CATALINA_OPTS
变量值:-Xmx128m -Xms64m -Xmn32m -Xss16m
3
b. 打开Tomcat根目录下的bin文件夹,编辑catalina.bat,将其中
的%CATALINA_OPTS%(共有四处)替换为:-Xmx128m -Xms64m -Xmn32m -Xss16m
一,jvm内存区域
1, 程序计数器
一块很小的内存空间,作用是当前线程所执行的字节码的行号指示器。
2, java栈
与程序计数器一样,java栈(虚拟机栈)也是线程私有的,其生命周期与线程相同。通常存放基本数据类型,对象引用(一个指向对象起始地址的引用指针或一个代表对象的句柄),reeturnAddress类型(指向一条字节码指令的地址)
栈区域有两种异常类型:如果线程请求的栈深度大于虚拟机所允许的深度,将抛StrackOverflowError异常;如果虚拟机栈可以动态扩展(大部分虚拟机都可动态扩展),当扩展时无法申请到足够的内存时会抛出OutOfMemoryError异常。
3, 本地方法栈
与虚拟机栈作用很相似,区别是虚拟机栈为虚拟机执行java方法服务,而本地方法栈则是为虚拟机用到的Native方法服务。和虚拟机栈一样可能抛出StackOverflowError和OutOfMemoryError异常。
4, java堆
java
Heap是jvm所管理的内存中最大的区域。JavaHeap是被所有线程共享的一块内存区域,在虚拟机启动时创建。主要存放对象实例。JavaHeap
是垃圾收集器管理的主要区域,其可细分为新生代和老年代。如果在堆中没有内存完成实例分配,并且也无法再扩展时,会抛出OutOfMemoryError
异常。
5, 方法区
与javaHeap一样是各个线程共享的内存区域,用于存放已被虚拟机加载的类信息、常量、静态变量、及时编译器编译后的代码等数据。当方法区无法满足内
存分配的需求时,将抛出OutOfMemoryError异常。方法同时包含常听说的运行时常量池,用于存放编译期生成的各种字面量和符号引用。
6, 直接内存
直接内存并不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域,是jvm外部的内存区域,这部分区域也可能导致OutOfMemoryError异常。
二,jvm参数
-Xss(StackSpace)栈空间
-Xms ,-Xmx(heap memory
space)堆空间:Heap是大家最为熟悉的区域,他是jvm用来存储对象实例的区域,Heap在32位的系统中最大为2G,其大小通过-Xms和
-Xmx来控制,-Xms为jvm启动时申请的最小Heap内存,默认为物理内存的1/64,但小于1G,-Xmx为jvm可申请的最大的Heap内存,
默认为物理内存的1/4,一般也小于1G,默认当空余堆内存小于40%时,jvm会最大Heap的大小到-Xmx指定大小,可通过
-XX:MinHeapFreeRatio来指定这个比例,当空余堆内存大于70%时,JVM会将Heap的大小往-Xms指定的大小调整,可通过
-XX:MaxHeapFreeRatio来指定这个比例,但通常为了避免频繁调整HeapSize的大小,将-Xms和-Xmx的值设为相同。
-XX:PermSize -XX:MaxPermSize :方法区持久代大小: 方法区域也是全局共享的,在一定的条件下它也会被 GC ,当方法区域需要使用的内存超过其允许的大小时,会抛出 OutOfMemory 的错误信息。
三,常见内存溢出错误解决办法
1, OutOfMemoryError异常
除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError(OOM)异常的可能,
Java Heap 溢出
一般的异常信息:java.lang.OutOfMemoryError:Java heap spacess
java堆用于存储对象实例,我们只要不断的创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,就会在对象数量达到最大堆容量限制后产生内存溢出异常。
出现这种异常,一般手段是先通过内存映像分析工具(如Eclipse Memory
Analyzer)对dump出来的堆转存快照进行分析,重点是确认内存中的对象是否是必要的,先分清是因为内存泄漏(Memory
Leak)还是内存溢出(Memory Overflow)。
如果是内存泄漏,可进一步通过工具查看泄漏对象到GC Roots的引用链。于是就能找到泄漏对象时通过怎样的路径与GC Roots相关联并导致垃圾收集器无法自动回收。
如果不存在泄漏,那就应该检查虚拟机的参数(-Xmx与-Xms)的设置是否适当。
2, 虚拟机栈和本地方法栈溢出
如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。
如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常
这里需要注意当栈的大小越大可分配的线程数就越少。
3, 运行时常量池溢出
异常信息:java.lang.OutOfMemoryError:PermGen space
如果要向运行时常量池中添加内容,最简单的做法就是使用String.intern()这个Native方法。该方法的作用是:如果池中已经包含一个等于
此String的字符串,则返回代表池中这个字符串的String对象;否则,将此String对象包含的字符串添加到常量池中,并且返回此String
对象的引用。由于常量池分配在方法区内,我们可以通过-XX:PermSize和-XX:MaxPermSize限制方法区的大小,从而间接限制其中常量
池的容量。
4, 方法区溢出
方法区用于存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。
异常信息:java.lang.OutOfMemoryError:PermGen space
方法区溢出也是一种常见的内存溢出异常,一个类如果要被垃圾收集器回收,判定条件是很苛刻的。在经常动态生成大量Class的应用中,要特别注意这点。
在解决java内存溢出问题之前,需要对jvm(java虚拟机)的内存管理有一定的认识。jvm管理的内存大致包括三种不同类型的内存区域:Permanent Generation space(永久保存区域)、Heap space(堆区域)、Java Stacks(Java栈)。其中永久保存区域主要存放Class(类)和Meta的信息,Class第一次被Load的时候被放入PermGen space区域,Class需要存储的内容主要包括方法和静态属性。堆区域用来存放Class的实例(即对象),对象需要存储的内容主要是非静态属性。每次用new创建一个对象实例后,对象实例存储在堆区域中,这部分空间也被jvm的垃圾回收机制管理。而Java栈跟大多数编程语言包括汇编语言的栈功能相似,主要基本类型变量以及方法的输入输出参数。Java程序的每个线程中都有一个独立的堆栈。容易发生内存溢出问题的内存空间包括:Permanent Generation space和Heap space。
第一种OutOfMemoryError: PermGen space
发生这种问题的原意是程序中使用了大量的jar或class,使java虚拟机装载类的空间不够,与Permanent Generation space有关。解决这类问题有以下两种办法:
增加java虚拟机中的XX:PermSize和XX:MaxPermSize参数的大小,其中XX:PermSize是初始永久保存区域大小,XX:MaxPermSize是最大永久保存区域大小。如针对tomcat6.0,在catalina.sh 或catalina.bat文件中一系列环境变量名说明结束处(大约在70行左右) 增加一行: JAVA_OPTS=" -XX:PermSize=64M -XX:MaxPermSize=128m" 如果是windows服务器还可以在系统环境变量中设置。感觉用tomcat发布sprint+struts+hibernate架构的程序时很容易发生这种内存溢出错误。使用上述方法,我成功解决了部署ssh项目的tomcat服务器经常宕机的问题。
清理应用程序中web-inf/lib下的jar,如果tomcat部署了多个应用,很多应用都使用了相同的jar,可以将共同的jar移到tomcat共同的lib下,减少类的重复加载。这种方法是网上部分人推荐的,我没试过,但感觉减少不了太大的空间,最靠谱的还是第一种方法。
第二种OutOfMemoryError: Java heap space
发生这种问题的原因是java虚拟机创建的对象太多,在进行垃圾回收之间,虚拟机分配的到堆内存空间已经用满了,与Heap space有关。解决这类问题有两种思路:
检查程序,看是否有死循环或不必要地重复创建大量对象。找到原因后,修改程序和算法。 我以前写一个使用K-Means文本聚类算法对几万条文本记录(每条记录的特征向量大约10来个)进行文本聚类时,由于程序细节上有问题,就导致了Java heap space的内存溢出问题,后来通过修改程序得到了解决。
增加Java虚拟机中Xms(初始堆大小)和Xmx(最大堆大小)参数的大小。如:set JAVA_OPTS= -Xms256m -Xmx1024m
第三种OutOfMemoryError:unable to create new native thread
在java应用中,有时候会出现这样的错误:OutOfMemoryError: unable to create new native thread.这种怪事是因为JVM已经被系统分配了大量的内存(比如1.5G),并且它至少要占用可用内存的一半。有人发现,在线程个数很多的情况下,你分配给JVM的内存越多,那么,上述错误发生的可能性就越大。
那么是什么原因造成这种问题呢?
每一个32位的进程最多可以使用2G的可用内存,因为另外2G被操作系统保留。这里假设使用1.5G给JVM,那么还余下500M可用内存。这500M内存中的一部分必须用于系统dll的加载,那么真正剩下的也许只有400M,现在关键的地方出现了:当你使用Java创建一个线程,在JVM的内存里也会创建一个Thread对象,但是同时也会在操作系统里创建一个真正的物理线程(参考JVM规范),操作系统会在余下的400兆内存里创建这个物理线程,而不是在JVM的1500M的内存堆里创建。在jdk1.4里头,默认的栈大小是256KB,但是在jdk1.5里头,默认的栈大小为1M每线程,因此,在余下400M的可用内存里边我们最多也只能创建400个可用线程。
这样结论就出来了,要想创建更多的线程,你必须减少分配给JVM的最大内存。还有一种做法是让JVM宿主在你的JNI代码里边。
给出一个有关能够创建线程的最大个数的估算公式:
(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads
对于jdk1.5而言,假设操作系统保留120M内存:
1.5GB JVM: (2GB-1.5Gb-120MB)/(1MB) = ~380 threads
1.0GB JVM: (2GB-1.0Gb-120MB)/(1MB) = ~880 threads
对于栈大小为256KB的jdk1.4而言,
1.5GB allocated to JVM: ~1520 threads
1.0GB allocated to JVM: ~3520 threads
对于这个异常我们首先需要判断下,发生内存溢出时进程中到底都有什么样的线程,这些线程是否是应该存在的,是否可以通过优化来降低线程数; 另外一方面默认情况下java为每个线程分配的栈内存大小是1M,通常情况下,这1M的栈内存空间是足足够用了,因为在通常在栈上存放的只是基础类型的数据或者对象的引用,这些东西都不会占据太大的内存, 我们可以通过调整jvm参数,降低为每个线程分配的栈内存大小来解决问题,例如在jvm参数中添加-Xss128k将线程栈内存大小设置为128k。
我来说两句