linux tomcat jvm内存优化

PermGen space:全称是Permanent Generation space。就是说是永久保存的区域,用于存放Class和Meta信息,Class在被Load的时候被放入该区域
Heap space:存放Instance。

GC(Garbage Collection)应该不会对PermGen space进行清理
因此若是你的APP会LOAD不少CLASS的话,就极可能出现PermGen space错误
html

Java Heap分为3个区,Young,Old和Permanent。Young保存刚实例化的对象。当该区被填满时,GC会将对象移到Old区。Permanent区则负责保存反射对象,本文不讨论该区。java


JVM的Heap分配可使用-X参数设定,web

-Xms
初始Heap大小

-Xmx

java heap最大值

-Xmn

young generation的heap大小

JVM有2个GC线程。第一个线程负责回收Heap的Young区。第二个线程在Heap不足时,遍历Heap,将Young 区升级为Older区。Older区的大小等于-Xmx减去-Xmn,不能将-Xms的值设的过大,由于第二个线程被迫运行会下降JVM的性能。
为何一些程序频繁发生GC?有以下缘由:
l         程序内调用了System.gc()或Runtime.gc()。
l         一些中间件软件调用本身的GC方法,此时须要设置参数禁止这些GC。
l         Java的Heap过小,通常默认的Heap值都很小。
l         频繁实例化对象,Release对象。此时尽可能保存并重用对象,例如使用StringBuffer()和String()。
若是你发现每次GC后,Heap的剩余空间会是总空间的50%,这表示你的Heap处于健康状态。许多Server端的Java程序每次GC后最好能有65%的剩余空间。
经验之谈:
1ServerJVM最好将-Xms-Xmx设为相同值。为了优化GC,最好让-Xmn值约等于-Xmx1/3[2]
2.一个GUI程序最好是每1020秒间运行一次GC,每次在半秒以内完成[2]

注意:
1.增长Heap的大小虽然会下降GC的频率,但也增长了每次GC的时间。而且GC运行时,全部的用户线程将暂停,也就是GC期间,Java应用程序不作任何工做。
2.Heap大小并不决定进程的内存使用量。进程的内存使用量要大于-Xmx定义的值,由于Java为其余任务分配内存,例如每一个线程的Stack等。数组


Stack的设定
每一个线程都有他本身的Stack。缓存

-Xss    每一个线程的Stack大小tomcat

Stack的大小限制着线程的数量。若是Stack过大就好致使内存溢漏。-Xss参数决定Stack大小,例如-Xss1024K。若是Stack过小,也会致使Stack溢漏。服务器


关于maxMemory(),freeMemory()和totalMemory(): jvm


maxMemory()为JVM的最大可用内存,可经过-Xmx设置,默认值为物理内存的1/4,设值不能高于计算机物理内存; 性能


totalMemory()为当前JVM占用的内存总数,其值至关于当前JVM已使用的内存及freeMemory()的总和,会随着JVM使用内存的增长而增长; 测试


freeMemory()为当前JVM空闲内存,由于JVM只有在须要内存时才占用物理内存使用,因此freeMemory()的值通常状况下都很小,而JVM实际可用内存并不等于freeMemory(),而应该等于maxMemory()-

totalMemory()+freeMemory()。及其设置JVM内存分配

设置JVM内存的参数有四个: 


-Xmx    Java Heap最大值,默认值为物理内存的1/4,最佳设值应该视物理内存大小及计算机内其余内存开销而定; 


-Xms    Java Heap初始值,Server端JVM最好将-Xms和-Xmx设为相同值,开发测试机JVM能够保留默认值; 


-Xmn    Java Heap Young区大小,不熟悉最好保留默认值; 


-Xss    每一个线程的Stack大小,不熟悉最好保留默认值;

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

JVM 堆的设置是指java程序运行过程当中JVM能够调配使用的内存空间的设置.JVM在启动的时候会自动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。能够利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。




另 外须要考虑的是Java提供的垃圾回收机制。虚拟机的堆大小决定了虚拟机花费在收集垃圾上的时间和频度。收集垃圾能够接受的速度与应用有关,应该经过分析 实际的垃圾收集的时间和频率来调整。若是堆的大小很大,那么彻底垃圾收集就会很慢,可是频度会下降。若是你把堆的大小和内存的须要一致,彻底收集就很快, 可是会更加频繁。调整堆大小的的目的是最小化垃圾收集的时间,以在特定的时间内最大化处理客户的请求。在基准测试的时候,为保证最好的性能,要把堆的大小 设大,保证垃圾收集不在整个基准测试的过程当中出现。

若是系统花费不少的时间收集垃圾,请减少堆大小。一次 彻底的垃圾收集应该不超过3-5秒。若是垃圾收集成为瓶颈,那么须要指定代的大小,检查垃圾收集的详细输出,研究垃圾收集参数对性能的影响。通常说来,你 应该使用物理内存的80%做为堆大小。当增长处理器时,记得增长内存,由于分配能够并行进行,而垃圾收集不是并行的。


一 个要注意的地方:建议把内存的最高值跟最低值的差值缩小,否则会浪费不少内存的,最低值加大,最高值能够随便设,可是要根据实际的物理内存,若是内存设置 太大了,好比设置了512M最大内存,但若是没有512M可用内存,Tomcat就不能启动,还有可能存在内存被系统回收,终止进程的状况




如何设置Tomcat的JVM内存大小

Tomcat 自己不能直接在计算机上运行,须要依赖于硬件基础之上的操做系统和一个JVM。JAVA程序启动时JVM都会分配一个初始JVM内存和最大JVM内存给这 个应用程序。这个初始内存和最大内存在必定程度都会影响程序的性能。好比说在应用程序用到最大内存的时候,JVM是要先去作垃圾回收的动做,释放被占用的 一些内存。因此想调整Tomcat的启动时初始内存和最大内存就须要向JVM声明,通常的JAVA程序在运行均可以经过中-Xms-Xmx来调整应用程序 的初始内存和最大内存:


这 两个值的大小通常根据须要进行设置。初始化堆的大小执行了虚拟机在启动时向系统申请的内存的大小。通常而言,这个参数不重要。可是有的应用程序在大负载的 状况下会急剧地占用更多的内存,此时这个参数就是显得很是重要,若是虚拟机启动时设置使用的内存比较小而在这种状况下有许多对象进行初始化,虚拟机就必须 重复地增长内存来知足使用。因为这种缘由,咱们通常把-Xms和-Xmx设为同样大,而堆的最大值受限于系统使用的物理内存。通常使用数据量较大的应用程 序会使用持久对象,内存使用有可能迅速地增加。当应用程序须要的内存超出堆的最大值时虚拟机就会提示内存溢出,而且致使应用服务崩溃。所以通常建议堆的最 大值设置为可用JVM内存的最大值的80%。


Tomcat默承认以使用的内存为128MB,在较大型的应用项目中,这点内存是不够的,须要调大。有如下几种方法能够选用:


第一种方法:


Windows下,在文件/bin/catalina.bat,Unix下,在文件/bin/catalina.sh的前面,增长以下设置:


JAVA_OPTS='-Xms【初始化内存大小】-Xmx【可使用的最大内存】'


须要把这个两个参数值调大。例如:


JAVA_OPTS='-Xms256m-Xmx512m'


表示初始化内存为256MB,可使用的最大内存为512MB。


第二种方法:环境变量中设


变量名:JAVA_OPTS


变量值:-Xms512m-Xmx512m


第三种方法:前两种方法针对的是bin目录下有catalina.bat的状况(好比直接解压的Tomcat等),可是有些安装版的Tomcat下没有catalina.bat,这个时候能够采用以下方法,固然这个方法也是最通用的方法:


打 开tomcatHome/\bin/\tomcat5w.exe,点击Java选项卡,而后将会发现其中有这么两项:Initialmemorypool 和Maximummemorypool.Initialmemorypool这个就是初始化设置的内存的大小。Maximummemorypool这个是 最大JVM内存的大小设置完了就按肯定而后再重启TOMCAT你就会发现tomcat中jvm可用的内存改变了。




第三种:没法建立新的线程。


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


  这种怪事是由于JVM已经被系统分配了大量的内存(好比1.5G),而且它至少要占用可用内存的一半。有人发现,在线程个数不少的状况下,你分配给JVM的内存越多,那么,上述错误发生的可能性就越大。


   产生这种现象的缘由以下(从这个blog中了解到缘由:http://hi.baidu.com/hexiong/blog ... b10c2542a75b3c.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内存分配进行不一样的诊断才能从根本上解决问题。




 编辑tomcat的catalina.sh文件,在第一行的后面增长一句: 

JAVA_OPTS='-server -Xms256m -Xmx512m -XX:PermSize=128M -XX:MaxPermSize=256M' 

注 意:单引号不能少,-server表示以server模式运行(运行效率比默认的client高不少,本身云去测试),-Xms256m是最小内存,- Xmx512m是最大内存,其中的256与512可根据你本身的内存作相应调整,PermSize/MaxPermSize最小/最大堆大小.通常报内存 不足时,都是说这个过小,堆空间剩余小于5%就会警告,建议把这个稍微设大一点,不过要视本身机器内存大小来设置,我本身的文件以下: 

#!/bin/sh 

JAVA_OPTS='-server -Xms1024m -Xmx1024m XX:PermSize=128M -XX:MaxPermSize=256M' 




. 各个参数的含义什么? 


参数中-vmargs的意思是设置JVM参数,因此后面的其实都是JVM的参数了,咱们首先了解一下JVM内存管理的机制,而后再解释每一个参数表明的含义。 


◆堆(Heap)和非堆(Non-heap)内存 


按 照官方的说法:“Java 虚拟机具备一个堆,堆是运行时数据区域,全部类实例和数组的内存均今后处分配。堆是在 Java 虚拟机启动时建立的。”“在JVM中堆以外的内存称为非堆内存(Non-heap memory)”。能够看出JVM主要管理两种类型的内存:堆和非堆。简单来讲堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给 本身用的,因此方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每一个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法 的代码都在非堆内存中。 


◆堆内存分配 


JVM 初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40% 时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减小堆直到-Xms的最小限制。所以服务器通常设置-Xms、-Xmx相 等以免在每次GC 后调整堆的大小。 


◆非堆内存分配 


JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。 


◆JVM内存限制(最大值) 


首 先JVM内存限制于实际的最大物理内存(废话!呵呵),假设物理内存无限大的话,JVM内存的最大值跟操做系统有很大的关系。简单的说就32位处理器虽然 可控内存空间有4GB,可是具体的操做系统会给一个限制,这个限制通常是2GB-3GB(通常来讲Windows系统下为1.5G-2G,Linux系统 下为2G-3G),而64bit以上的处理器就不会有限制了。

相关文章
相关标签/搜索