Tomcat内存溢出的三种情况及解决办法分析

合集下载

几种常见的内存溢出与解决办法

几种常见的内存溢出与解决办法

⼏种常见的内存溢出与解决办法引起内存溢出的原因有很多种,常见的有以下⼏种: 1.内存中加载的数据量过于庞⼤,如⼀次从数据库取出过多数据; 2.集合类中有对对象的引⽤,使⽤完后未清空,使得JVM不能回收; 3.代码中存在死循环或循环产⽣过多重复的对象实体; 4.使⽤的第三⽅软件中的BUG; 5.启动参数内存值设定的过⼩;1.堆设置jvm值的⽅法是通过-Xms(堆的最⼩值),-Xmx(堆的最⼤值)2.栈设置栈⼤⼩的⽅法是设置-Xss参数3.PermGen space第三个异常是关于perm的异常内容,我们需要的是设置⽅法区的⼤⼩,实现⽅式是通过设置-XX:PermSize和-XX:MaxPermSize参数4.DirectMemory第四个异常估计遇到的⼈就不多了,是DirectMemory内存相关的DirectMemoruSize可以通过设置 -XX:MaxDirectMemorySize参数指定容量⼤⼩,如果不指定的话,那么就跟堆的最⼤值⼀致内存使⽤监控⼯具jvmstat 解決辦法:【情况⼀】:ng.OutOfMemoryError:Javaheapspace:这种是java堆内存不够,⼀个原因是真不够(如递归的层数太多等),另⼀个原因是程序中有死循环; 如果是java堆内存不够的话,可以通过调整JVM下⾯的配置来解决: -Xms3062m -Xmx3062m【情况⼆】 ng.OutOfMemoryError:GCoverheadlimitexceeded 【解释】:JDK6新增错误类型,当GC为释放很⼩空间占⽤⼤量时间时抛出;⼀般是因为堆太⼩,导致异常的原因,没有⾜够的内存。

【解决⽅案】: 1、查看系统是否有使⽤⼤内存的代码或死循环; 2、通过添加JVM配置,来限制使⽤内存: -XX:-UseGCOverheadLimit【情况三】: ng.OutOfMemoryError:PermGenspace:这种是P区内存不够,可通过调整JVM的配置: -XX:MaxPermSize=128m -XXermSize=128m 【注】: JVM的Perm区主要⽤于存放Class和Meta信息的,Class在被Loader时就会被放到PermGenspace,这个区域成为年⽼代,GC在主程序运⾏期间不会对年⽼区进⾏清理, 默认是64M⼤⼩,当程序需要加载的对象⽐较多时,超过64M就会报这部分内存溢出了,需要加⼤内存分配,⼀般128m⾜够。

导致内存溢出原因有哪些内存溢出问题又如何解决

导致内存溢出原因有哪些内存溢出问题又如何解决

导致内存溢出原因有哪些内存溢出问题又如何解决内存溢出的原因以及解决方法1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据; 2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收; 3.代码中存在死循环或循环产生过多重复的对象实体; 4.使用的第三方软件中的BUG; 5.启动参数内存值设定的过小内存溢出的解决方案:第一步,修改JVM启动参数,直接增加内存。

(-某m,-某m某参数一定不要忘记加。

)第二步,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。

第三步,对代码进行走查和分析,找出可能发生内存溢出的位置。

重点排查以下几点: 1.检查对数据库查询中,是否有一次获得全部数据的查询。

一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。

这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。

因此对于数据库查询尽量采用分页的方式查询。

2.检查代码中是否有死循环或递归调用。

3.检查是否有大循环重复产生新对象实体。

4.检查对数据库查询中,是否有一次获得全部数据的查询。

一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。

这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。

因此对于数据库查询尽量采用分页的方式查询。

5.检查Lit、MAP等集合对象是否有使用完后,未清除的问题。

Lit、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。

第四步,使用内存查看工具动态查看内存使用情况。

Tomcat运行Java Web内存溢出总结

Tomcat运行Java Web内存溢出总结

Tomcat运行Java Web内存溢出总结假如JVM里运行的程序, 它的内存堆和持久存储区域的都满了,这个时候程序还想创建对象实例的话,垃圾收集器就会启动,试图释放足够的内存来创建这个对象。

这个时候假如垃圾收集器没有能力释放出足够的内存,它就会抛出OutOfMemoryError内存溢出错误。

SUN JVM 的内存管理方式: SUN的JVM是类似人类家族,也就是在一个地方创建对象,在它长久占领空间之前给它多次死亡的机会,SUN JVM会划分为: 1. 衰老的一代(Young generation),包括EDEN和2个残存物空间(动身地和目的地the From space and the To space) 2. 老一代(Old generation) 3. 永远的一代(Peanent generation) Java 虚拟机的运行时数据区普通分类如下(不一定是物理划分): 1. 堆:主要存放对象实例,线程分享 2. 栈:主要存储特定线程的办法调用状态,线程独占 3. 本地办法栈:存储本地办法的调用状态,线程独占 4. PC寄存器:学过操作系统课程的都知道,线程独占 5. 办法区:主要存储了类型信息,线程分享因此,在抛出内存溢出错误的时候,普通都会提醒内存泄露的种类,普通也都是根据区域举行划分: 1. 堆(heap)内存泄漏ng.OutOfMemoryError: Javaheap space:大家都比较认识,通过设置-Xms2048m -Xmx4096m 可以解决 2. 栈(stack)内存泄漏:当前线程运行期间维护的中间变量等信息过多,例如频繁的死循环引起stack over flow 3. 办法区(permanent heap)内存泄漏,即ng.OutOfMemoryError: PermGen space:发生的缘由和类型装载、类型卸载有挺直的关系,通过设置-XX:MaxNewSize=256m -XX:MaxPermSize=256m可以解决。

Tomcat内存溢出及线程紊乱问题研究

Tomcat内存溢出及线程紊乱问题研究

Tomcat内存溢出及线程紊乱问题研究摘要:在很多基于B/S结构的网站架构中,WEB容器内存溢出及线程紊乱问题比较隐蔽,很多时候在测试阶段并不能发现,只有在现实中大规模数据和高并发量的情况下问题才逐渐的暴露出来。

因此,在网站正式发布前代码进行走查和技术改进,并修改相关服务器软件的配置,可以在很大程度上减少此类事件的发生。

本文以Tomcat为例,对WEB容器在数据传输过程中内存溢出及线程紊乱的表现、原因及解决方案作了简要论述。

关键词:Tomcat;WEB容器;内存溢出;线程紊乱随着Internet技术的普及,各地方学校、研究所和商业单位都在积极进行基础教育资源网和资源库的建设。

然而,随着资源网使用人数的不断增加,其并发量也在急剧增长,对WEB服务器的承压性和稳定性提出了新的挑战。

然而大多数WEB容器均有内存限制,因此,在服务器没有内存还有很大空缺的情况下,WEB容器内存首先溢出,经常报“OutOfMemory”错误,并与其他因素一道引发了线程紊乱,导致应用系统的某些功能重复执行,并且引起了数据库服务器崩溃、系统越来越慢直到死机等问题。

随着互联网技术的发展,基于WEB容器大规模数据传输以及并发量的需求已经日渐突出,而数据传输效率、WEB应用服务器性能以及应用系统的稳定性等因素直接影响了数据传输的质量。

在以Tomcat为WEB容器的环境中,若以上问题处理不当,则很多时候表现为Tomcat内存溢出以及线程紊乱,造成服务器宕机,严重影响正常的网站运行。

1Tomcat内存溢出及线程紊乱的主要表现Tomcat内存溢出主要是通过系统速度、系统性能表现以及系统日志来反映的。

通过对日志文件和系统表现的分析与判断,即可断定是否为内存溢出;线程紊乱是指在Web容器中发生的线程异常的情况,其很多时候是在内存溢出之后出现的,通过对应用系统的操作日志及WEB容器的相关日志即可判断。

1.1Tomcat内存溢出主要表现1)系统的速度越来越慢,甚至出现死机的现象。

内存溢出的三种情况及系统配置解决方案

内存溢出的三种情况及系统配置解决方案

内存溢出的三种情况及系统配置解决方案内存溢出是指程序在运行过程中申请的内存超过了系统或者进程所能提供的上限。

导致内存溢出的原因可能是程序中存在内存泄漏、内存分配过多或者递归调用过深等。

下面将介绍三种常见的内存溢出情况及其系统配置解决方案。

1.程序内存泄漏导致内存溢出:内存泄漏指程序在运行过程中动态分配内存空间后,没有对其进行释放,导致一部分内存无法再次使用。

长时间运行的程序中,如果内存泄漏较为严重,系统可用内存会不断减少,直到最终耗尽所有内存资源。

解决方案:使用内存泄漏检测工具来检测和修复程序中的内存泄漏问题。

同时,可以考虑使用自动内存管理的编程语言,如Java和Python,在程序运行过程中自动回收未使用的内存。

2.内存分配过多导致内存溢出:解决方案:优化程序的内存使用,尽可能减小内存分配的数量和大小。

可以通过使用更高效的内存管理算法来减少内存碎片,或者使用内存池技术来提前分配一定量的内存供程序使用。

3.递归调用过深导致内存溢出:递归函数在每次调用时会将一定量的数据压入栈中,如果递归调用层数过深,栈的空间可能会超过系统的限制,从而导致内存溢出。

这种情况通常发生在没有设置递归终止条件或者递归层数过多的情况下。

解决方案:优化递归算法,设置合适的递归终止条件,避免递归调用过深。

如果无法避免使用递归算法,可以考虑使用尾递归或者迭代算法来替代递归调用,减少栈的压力。

在系统配置方面,可以采取以下措施来预防和解决内存溢出问题:1.增加系统内存容量:如果内存溢出是由于系统可用内存不足引起的,可以考虑增加系统的内存容量。

这可以通过增加物理内存条或者使用虚拟内存技术来实现。

虚拟内存技术会将部分磁盘空间用作缓存,并将一部分数据暂时存储在磁盘上,以释放内存空间。

2. 调整JVM参数:对于使用Java虚拟机(JVM)的应用程序,可以通过调整JVM的参数来控制内存的分配和管理。

例如,可以通过设置-Xmx参数来限制JVM使用的最大堆内存大小,或者通过设置-XX:MaxPermSize参数来限制JVM使用的最大持久代(PermGen)内存大小。

内存溢出的三种情况及系统配置解决方案

内存溢出的三种情况及系统配置解决方案

内存溢出的三种情况及系统配置解决方案内存溢出是指程序在运行过程中申请的内存超过了系统所分配的内存空间,导致程序崩溃或出现异常。

内存溢出通常是由于程序设计或系统配置问题引起的。

以下是三种常见的内存溢出情况及相应的系统配置解决方案。

1.单个进程占用内存过大:当一些进程在运行过程中占用的内存超过系统分配的限制时,就会导致内存溢出。

这种情况通常发生在大型应用程序或者后台服务运行时。

解决方案:-增加物理内存:在服务器或计算机中增加物理内存,以满足进程运行所需的内存空间。

-调整虚拟内存:将物理内存和虚拟内存结合使用,允许操作系统使用虚拟内存作为物理内存的扩展,从而提供更大的内存容量。

-优化应用程序:通过优化程序代码、降低内存使用、合理管理资源等方法,减少进程对内存的占用。

2.长时间运行的应用程序产生泄露:有些应用程序在长时间运行后会产生内存泄露的问题,即分配并使用内存后没有将其释放,导致内存占用逐渐增加,最终导致内存溢出。

解决方案:-使用垃圾回收机制:在一些支持垃圾回收的编程语言中,通过垃圾回收机制可以自动释放未使用的内存。

开发人员可以使用这些机制来解决内存泄露问题。

-引入内存监控工具:使用内存监控工具来检测应用程序中的内存泄露,定位并解决导致内存泄露的代码问题。

-定期重启应用程序:定期重启应用程序可以清理内存,防止内存泄露导致内存溢出。

3.大规模并发请求导致内存压力增加:在高并发的情况下,当系统同时处理大量的请求时,每个请求所占用的内存可能累积增加,导致整体内存压力增加,最终出现内存溢出。

解决方案:-加大系统负载均衡能力:通过增加负载均衡器、引入缓存机制等方式,将请求分散到多台服务器上,减少单台服务器的内存压力。

-优化数据库访问:对于一些频繁读写数据库的操作,可以通过合理的数据库设计、使用索引、缓存查询结果等方法,减少对数据库的访问,降低内存压力。

-调整服务器配置:合理设置服务器的最大并发连接数、线程池大小等参数,根据实际需求分配内存资源。

Tomcat内存溢出分析及解决方法

Tomcat内存溢出分析及解决方法Tomcat内存溢出分析及解决方法JVM管理两种类型的内存,堆和非堆。

堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的。

它和堆不同,运行期内GC不会释放空间。

一、内存溢出类型1、ng.OutOfMemoryError: PermGen spaceJVM管理两种类型的内存,堆和非堆。

堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的。

它和堆不同,运行期内GC不会释放空间。

如果web app用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较小,超出了也会导致这块内存的占用过多造成溢出,或者tomcat热部署时侯不会清理前面加载的环境,只会将context更改为新部署的,非堆存的内容就会越来越多。

PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的应用中有很CLASS的话,就很可能出现PermGen space错误,这种错误常见在web服务器对JSP进行pre compile的时候。

如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。

一个最佳的配置例子:(经过本人验证,自从用此配置之后,再未出现过tomcat死掉的情况)set JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m在linux下在tomcathome/conf/catalina.sh中加上如标红所示的一句代码:可以增加tomcat jvm 的内存,这样就不容易出现内存溢出的现象了!# ----- Execute The Requested Command -----------------------------------------JAVA_OPTS="-server -Xms512m -Xmx2048m -XX:PermSize=128m -XX:MaxNewSize=256m -XX:MaxPermSize=256m"# Bugzilla 37848: only output this if we have a TTY2、ng.OutOfMemoryError: Javaheap space第一种情况是个补充,主要存在问题就是出现在这个情况中。

解决tomcat内存溢出问题

TOMCAT出错:ng.OutOfMemoryError: Java heap spaceIf Java runs out of memory, the following error occurs:Exception in thread "main" ng.OutOfMemoryError: Java heap spaceJava heap size can be increased as follows:java -Xms<initial heap size> -Xmx<maximum heap size>Defaults are:java -Xms32m -Xmx128m可以在windows 更改系统环境变量加上JA V A_OPTS=-Xms256m -Xmx512mEclipse中出现ng.OutOfMemoryError: Java heap spaceng.OutOfMemoryError: Java heap space错误unix/linux/tomcat/bin/catalina.sh 加上下面的命令:JA V A_OPTS="-Xms256m -Xmx512m "Windows在tomcat->bin的catalina.bat里加set JA V A_OPTS=-Xms256m -Xmx512m -Djava.awt.headless=true (256和512分别是MIN和MAX内存)位置在: rem Guess CATALINA_HOME if not defined 这行的下面加合适.在myeclipse/eclipse中的windows->preferences->Java->Installed JRES->edit->Default VM Arguments那一个文本框里,添加-Xms256m -Xmx512m这样就可以了!点“Edit”Default VM Arguments:那一个文本框里添加:-Xms256m -Xmx512mng.OutOfMemoryError: Java heap space使用Java程序从数据库中查询大量的数据时出现异常:ng.OutOfMemoryError: Java heap space在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。

内存溢出的原因有哪些?怎么解决?

内存溢出的原因有哪些?怎么解决?内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

那么当你遇到这种情况时该怎么办呢?今天小编为大家整理了一些解决方法,下面我们一起来看看吧!简介内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。

一个盘子用尽各种方法只能装4个果子,你装了5个,结果掉倒地上不能吃了。

这就是溢出!比方说栈,栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。

就是分配的内存不足以放下数据项序列,称为内存溢出.以发生的方式来分类,内存泄漏可以分为4类:1. 常发性内存泄漏。

发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。

2. 偶发性内存泄漏。

发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。

常发性和偶发性是相对的。

对于特定的环境,偶发性的也许就变成了常发性的。

所以测试环境和测试方法对检测内存泄漏至关重要。

3. 一次性内存泄漏。

发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。

比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。

4. 隐式内存泄漏。

程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。

严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。

但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。

所以,我们称这类内存泄漏为隐式内存泄漏。

从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。

tomcat OutOfMemory错误解决方法

tomcat OutOfMemory错误解决方法部署应用服务到tomcat下,可能会抛出内存溢出异常,如下:Exception in thread "Timer-1" ng.OutOfMemoryError: PermGen space为了解决tomcat在大进行大并发请求时,出现内存溢出的问题,请修改tomcat的内存大小,其中分为以下两种方式:一、使用catalina.bat 等命令行方式运行的tomcat1、windows环境下,修改tomcat\bin\Catalina.bat 文件在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 -Xmx512m2、linux环境下,打开在Tomcat的安装目录的bin文件的 ./bin/catalina.sh 文件,进入编辑状态.在注释后面加上如下脚本:JAVA_OPTS='-Xms512m -Xmx1024m'JAVA_OPTS="$JAVA_OPTS -server -XX:PermSize=64M -XX:MaxPermSize=256m"或者,在echo "Using CATALINA_BASE: $CATALINA_BASE" 下添加一行echo "Using CATALINA_BASE: $CATALINA_BASE"JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m"echo "Using CATALINA_HOME: $CATALINA_HOME"echo "Using CATALINA_TMPDIR: $CATALINA_TMPDIR"说明:JAVA_OPTS='-Xms512m -Xmx1024m' 是设置Tomcat使用的内存的大小; -XX:PermSize=64M-XX:MaxPermSize=256m 指定类空间(用于加载类)的内存大小保存后,重新以命令行的方式运行tomcat ,即可,然后通过最后面介绍的如何观察tomcat现有内存情况的方法进行查看是否已经变更成功。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Tomcat内存溢出的三种情况及解决办法分析
2009-08-24 15:25:08 来源: 作者:
在生产环境中tomcat内存设置不好很容易出现内存溢出。

造成内存原因是不一样的,当然处理方式也不一样。

Tomcat内存溢出的原因
在生产环境中tomcat内存设置不好很容易出现内存溢出。

造成内存原因是不一样的,当然处理方式也不一样。

这里根据平时遇到的情况和相关资料进行一个总结。

常见的一般会有下面三种情况:
1.OutOfMemoryError: Java heap space
2.OutOfMemoryError: PermGen space
3.OutOfMemoryError: unable to create new native thread.
Tomcat内存溢出解决方案
对于前两种情况,在应用本身没有内存泄露的情况下可以用设置tomcat jvm参数来解决。

(-Xms -Xmx -XX:PermSize -XX:MaxPermSize)
最后一种可能需要调整操作系统和tomcat jvm参数同时调整才能达到目的。

第一种:是堆溢出。

在JVM中如果98%的时间是用于GC且可用的 Heap size 不足2%的时候将抛出此异常信息。

没有内存泄露的情况下,调整-Xms -Xmx参数可以解决。

-Xms:初始堆大小
-Xmx:最大堆大小
但堆的大小受下面三方面影响:
1.相关操作系统的数据模型(32-bt还是64-bit)限制;(32位系统下,一般限制在1.5G~2G;我在2003 server 系统下(物理内存:4G和6G,jdk:1.6)测试 1612M,64为操作系统对内存无限制。


2.系统的可用虚拟内存限制;
3.系统的可用物理内存限制。

堆的大小可以使用 java -Xmx***M version 命令来测试。

支持的话会出现jdk的版本号,不支持会报错。

-Xms -Xmx一般配置成一样比较好比如set JAVA_OPTS= -Xms1024m -Xmx1024m
第二种:永久保存区域溢出
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域。

这一部分用于存
放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和和存放Instance的Heap区
域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你
的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。

这种错误常见在web服务器对JSP进行pre compile的时候。

但目前的hibernate和spring项目中也很容易出现这样的问
题。

/topic/80620?page=1 的帖子有讨论的这个问题。

可能是由于这些框架会动态class,而且jvm的gc是不会清理PemGen space的,导致内存溢出。

这一个一般是加大-XX:PermSize -XX:MaxPermSize 来解决问题。

-XX:PermSize 永久保存区域初始大小
-XX:PermSize 永久保存区域初始最大值
这一般结合第一条使用,比如 set JAVA_OPTS= -Xms1024m -Xmx1024m -XX:PermSize=128M -XX:PermSize=256M
有一点需要注意:java -Xmx***M version 命令来测试的最大堆内存是 -Xmx与 -XX:PermSize的和比如系统支持最大的jvm堆大小事1.5G,那 -Xmx1024m -XX:PermSize=768M 是无法运行的。

第三种:无法创建新的线程。

这种现象比较少见,也比较奇怪,主要是和jvm与系统内存的比例有关。

这种怪事是因为JVM已经被系统分配了大量的内存(比如1.5G),并且它至少要占用可用内存的一半。

有人发现,在线程个数很多的情况下,你分配给JVM的内存越多,那么,上述错误发生的可能性就越大。

产生这种现象的原因如下(从这个blog中了解到原
因:/hexiong/blog/item/16dc9e518fb10c2542a75b3c.html):
每一个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
在2000/XP/2003的boot.ini里头有一个启动选项,好像是:/PAE /3G ,可以让用户进程最大内存扩充至3G,这时操作系统只能占用最多1G的虚存。

那样应该可以让JVM创建更多的线程。

因此这种情况需要结合操作系统进行相关调整。

因此:我们需要结合不同情况对tomcat内存分配进行不同的诊断才能从根本上解决问题。

相关文档
最新文档