【Tomcat】Tomcat配置JVM参数步骤
这⾥向⼤家描述⼀下如何使⽤Tomcat配置参数,Tomcat本⾝不能直接在计算机上运⾏,需要依赖于硬件基础之上的操作系统和⼀个java虚拟机。您可以选择⾃⼰的需要选择不同的操作系统和对应的JDK的版本,但还是推荐您使⽤Sun公司发布的JDK。
jvm在client模式,进⾏内存回收时,会停下所有的其它⼯作,带回收完毕才去执⾏其它任务,在这期间eclipse就卡住了。所以适当的增加jvm申请的内存⼤⼩来减少其回收的次数甚⾄不回收,就会是卡的现象有明显改善。
主要通过以下的⼏个jvm参数来设置堆内存的:
-Xmx512m最⼤总堆内存,⼀般设置为物理内存的1/4
-Xms512m初始总堆内存,⼀般将它设置的和最⼤堆内存⼀样⼤,这样就不需要根据当前堆使⽤情况⽽调整堆的⼤⼩了
-Xmn192m年轻带堆内存,sun官⽅推荐为整个堆的3/8
堆内存的组成总堆内存 = 年轻带堆内存 + 年⽼带堆内存 + 持久带堆内存
年轻带堆内存对象刚创建出来时放在这⾥
年⽼带堆内存对象在被真正会回收之前会先放在这⾥
持久带堆内存class⽂件,元数据等放在这⾥
-XX:PermSize=128m持久带堆的初始⼤⼩
-XX:MaxPermSize=128m持久带堆的最⼤⼤⼩,eclipse默认为256m。如果要编译jdk这种,⼀定要把这个设的很⼤,因为它的类太多了。
Tomcat配置JVM参数
Tomcat本⾝不能直接在计算机上运⾏,需要依赖于硬件基础之上的操作系统和⼀个java虚拟机。您可以选择⾃⼰的需要选择不同的操作系统和对应的 JDK 的版本(只要是符合Sun发布的Java规范的),但我们推荐您使⽤Sun公司发布的JDK。确保您所使⽤的版本是最新的,因为Sun公司和其它⼀些公司⼀直在为提⾼性能⽽对java虚拟机做⼀些升级改进。⼀些报告显⽰JDK1.4在性能上⽐JDK1.3提⾼了将近10%到20%。
可以给Java虚拟机设置使⽤的内存,但是如果你的选择不对的话,虚拟机不会补偿。可通过命令⾏的⽅式改变虚拟机使⽤内存的⼤⼩。如下表所⽰有两个参数⽤来设置虚拟机使⽤内存的⼤⼩。
参数描述
-Xms      JVM初始化堆的⼤⼩
-Xmx      JVM堆的最⼤值
这两个值的⼤⼩⼀般根据需要进⾏设置。初始化堆的⼤⼩执⾏了虚拟机在启动时向系统申请的内存的⼤⼩。⼀般⽽⾔,这个参数不重要。但是有的应⽤程序在⼤负载的情况下会急剧地占⽤更多的内存,此时这个参数就是显得⾮常重要,如果虚拟机启动时设置使⽤的内存⽐较⼩⽽在这种情况下有许多对象进⾏初始化,虚拟机就必须重复地增加内存来满⾜使⽤。
由于这种原因,我们⼀般把-Xms和-Xmx设为⼀样⼤,⽽堆的最⼤值受限于系统使⽤的物理内存。⼀般使⽤数据量较⼤的应⽤程序会使⽤持久对象,内存使⽤有可能迅速地增长。当应⽤程序需要的内存超出堆的最⼤值时虚拟机就会提⽰内存溢出,并且导致应⽤服务崩溃。因此⼀般建议堆的最⼤值设置为可⽤内存的最⼤值的80%。
Tomcat默认可以使⽤的内存为128MB,在较⼤型的应⽤项⽬中,这点内存是不够的,需要调⼤。
Windows下,在⽂件/bin/catalina.bat,Unix下,在⽂件/bin/catalina.sh的前⾯,增加如下设置:
JAVA_OPTS='-Xms【初始化内存⼤⼩】
-Xmx【可以使⽤的最⼤内存】'
需要把这个两个参数值调⼤。例如:
1. JAVA_OPTS'-Xms256m-Xmx512m'
表⽰初始化内存为256MB,可以使⽤的最⼤内存为512MB。
另外需要考虑的是Java提供的垃圾回收机制。虚拟机的堆⼤⼩决定了虚拟机花费在收集垃圾上的时间和频度。收集垃圾可以接受的速度与应⽤有关,应该
通过分析实际的垃圾收集的时间和频率来调整。如果堆的⼤⼩很⼤,那么完全垃圾收集就会很慢,但是频度会降低。如果你把堆的⼤⼩和内存的需要⼀致,完全收集就很快,但是会更加频繁。调整堆⼤⼩的的⽬的是最⼩化垃圾收集的时间,以在特定的时间内最⼤化处理客户的请求。在基准测试的时候,为保证最好的性能,要把堆的⼤⼩设⼤,保证垃圾收集不在整个基准测试的过程中出现。
如果系统花费很多的时间收集垃圾,请减⼩堆⼤⼩。⼀次完全的垃圾收集应该不超过3-5秒。如果垃圾收集成为瓶颈,那么需要指定代的⼤⼩,检查垃圾收集的详细输出,研究垃圾收集参数对性能的影响。⼀般说来,你应该使⽤物理内存的80%作为堆⼤⼩。当增加处理器时,记得增加内存,因为分配可以并⾏进⾏,⽽垃圾收集不是并⾏的。
1:建议⽤64位操作系统,Linux下64位的jdk⽐32位jdk要慢⼀些,但是吃得内存更多,吞吐量更⼤。
2:XMX和XMS设置⼀样⼤,MaxPermSize和MinPermSize设置⼀样⼤,这样可以减轻伸缩堆⼤⼩带来的压⼒。
3:调试的时候设置⼀些打印JVM参数,如-XX:+PrintClassHistogram-XX:+PrintGCDetails- XX:+PrintGCTimeStamps-XX:+PrintHeapAtGC-
Xloggc:log/gc.log,这样可以从gc.log⾥看出⼀些端倪出来。
4:系统停顿的时候可能是GC的问题也可能是程序的问题,多⽤jmap和jstack查看,或者killall-3java,然后查看java控制台⽇志,能看出很多问题。有⼀次,⽹站突然很慢,jstack⼀看,原来是⾃⼰写的URLConnection连接太多没有释放,改⼀下程序就OK了。
5:仔细了解⾃⼰的应⽤,如果⽤了缓存,那么年⽼代应该⼤⼀些,缓存的HashMap不应该⽆限制长,建议采⽤LRU算法的Map做缓存,LRUMap的最⼤长度也要根据实际情况设定。
6:垃圾回收时promotionfailed是个很头痛的问题,⼀般可能是两种原因产⽣,第⼀个原因是救助空间不够,救助空间⾥的对象还不应该被移动到年⽼代,但年轻代⼜有很多对象需要放⼊救助空间;第⼆个原因是年⽼代没有⾜够的空间接纳来⾃年轻代的对象;这两种情况都会转向FullGC,⽹站停顿时间较长。
第⼀个原因我的最终解决办法是去掉救助空间,设置-XX:SurvivorRatio=65536- XX:MaxTenuringThreshold=0即可,第⼆个原因我的解决办法是设置CMSInitiatingOccupancyFraction 为某个值(假设70),这样年⽼代空间到70%时就开始执⾏CMS,年⽼代有⾜够的空间接纳来⾃年轻代的对象。
7:不管怎样,永久代还是会逐渐变满,所以隔三差五重起java服务器是必要的,我每天都⾃动重起。
8:采⽤并发回收时,年轻代⼩⼀点,年⽼代要⼤,因为年⽼⼤⽤的是并发回收,即使时间长点也不会影响其他程序继续运⾏,⽹站不会停顿。
我的最终配置如下(系统8G内存),每天⼏百万pv⼀点问题都没有,⽹站没有停顿,2009年⽹站没有因为内存问题down过机。
$JAVA_ARGS.="-Dresin.home=$SERVER_ROOT
-server-Xms6000M-Xmx6000M-Xmn500M
-XX:PermSize=500M-XX:MaxPermSize=500M
-XX:SurvivorRatio=65536
-XX:MaxTenuringThreshold=0
-Xnoclassgc
-XX:+DisableExplicitGC
XX:+UseParNewGC-XX:+UseConcMarkSweepGC
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0
-XX:+CMSClassUnloadingEnabled
-XX:-CMSParallelRemarkEnabled
-XX:CMSInitiatingOccupancyFraction=90
-XX:SoftRefLRUPolicyMSPerMB=0-XX:+PrintClassHistogram
-XX:+PrintGCDetails-XX:+PrintGCTimeStamps-XX:+PrintHeapAtGC
tomcat虚拟主机怎么设置-
Xloggc:log/gc.log";
说明⼀下,-XX:SurvivorRatio=65536,-XX:MaxTenuringThreshold=0就是去掉了救助空间;
-Xnoclassgc禁⽤类垃圾回收,性能会⾼⼀点;
-XX:+DisableExplicitGC禁⽌(),免得程序员误调⽤gc⽅法影响性能;
-XX:+UseParNewGC,对年轻代采⽤多线程并⾏回收,这样收得快;
带CMS参数的都是和并发回收相关的,不明⽩的可以上⽹搜索;
CMSInitiatingOccupancyFraction,这个参数设置有很⼤技巧,基本上满⾜(Xmx-Xmn)*(100- CMSInitiatingOccupancyFraction)/100>=Xmn就不会出现promotionfailed。在我的应⽤中 Xmx是6000,Xmn是500,那么Xmx-Xmn是5500兆,也就是年⽼代有5500 兆,CMSInitiatingOccupancyFraction=90说明年⽼代到90%满的时候开始执⾏对年⽼代的并发垃圾回收(CMS),这时还剩10%的空间是5500*10%=550兆,所以即使Xmn(也就是年轻代共500兆)⾥所有对象都搬到年⽼代⾥,550兆的空间也⾜够了,所以只要满⾜上⾯的公式,就不会出现垃圾回收时的promotionfailed;
SoftRefLRUPolicyMSPerMB这个参数我认为可能有点⽤,官⽅解释是softlyreachableobjectswillremainaliveforsomeamountoftimeafterthelasttimetheywerereferenced.
Thedefaultvalueisonesecondoflifetimeperfreemegabyteintheheap,我觉得没必要等1秒;
⽹上其他介绍JVM参数的也⽐较多,估计其中⼤部分是没有遇到promotionfailed,或者访问量太⼩没有机会遇到,(Xmx-Xmn)* (100-CMSInitiatingOccupancyFraction)/100>=Xmn这个公式绝对是原创,真遇到 promotionfailed了,还得这么处理。
JVM内存设置原理
默认的java虚拟机的⼤⼩⽐较⼩,在对⼤数据进⾏处理时java就会报错:java.lang.OutOfMemoryError。设置jvm内存的⽅法,对于单独的.class,可以⽤下⾯的⽅法对Test运⾏时的jvm内存进⾏设置。
java-Xms64m-Xmx256mTest
-Xms是设置内存初始化的⼤⼩
-Xmx是JVM内存设置中设置最⼤能够使⽤内存的⼤⼩(最好不要超过物理内存⼤⼩)
在weblogic中,可以在d中对每个domain虚拟内存的⼤⼩进⾏设置,默认的设置是在d⾥⾯。简单介绍了JVM内存设置,下⾯我们看⼀下JVM内存的调优。
JVM内存的调优
1.Heap设定与垃圾回收
JavaHeap分为3个区,Young,Old和Permanent。Young保存刚实例化的对象。当该区被填满时,GC会将对象移到Old区。Permanent区则负责保存反射对象,本⽂不讨论该区。JVM的Heap分配可以使⽤-X参数设定,
JVM有2个GC线程。
第⼀个线程负责回收Heap的Young区。
第⼆个线程在Heap不⾜时,遍历Heap,将Young区升级为Older区。Older区的⼤⼩等于-Xmx减去-Xmn,不能将-Xms的值设的过⼤,因为第⼆个线程被迫运⾏会降低JVM的性能。
为什么⼀些程序频繁发⽣GC?有如下原因:
◆程序内调⽤了()或()。
◆⼀些中间件软件调⽤⾃⼰的GC⽅法,此时需要设置参数禁⽌这些GC。
◆Java的Heap太⼩,⼀般默认的Heap值都很⼩。
◆频繁实例化对象,Release对象。此时尽量保存并重⽤对象,例如使⽤StringBuffer()和String()。
如果你发现每次GC后,Heap的剩余空间会是总空间的50%,这表⽰你的Heap处于健康状态。许多Server端的Java程序每次GC后最好能有65%的剩余空间。
经验之谈:
1.Server端JVM最好将-Xms和-Xmx设为相同值。为了优化GC,最好让-Xmn值约等于-Xmx的1/3[2]。
2.⼀个GUI程序最好是每10到20秒间运⾏⼀次GC,每次在半秒之内完成[2]。
注意:
1.增加Heap的⼤⼩虽然会降低GC的频率,但也增加了每次GC的时间。并且GC运⾏时,所有的⽤户线程将暂停,也就是GC期间,Java应⽤程序不做任何⼯作。
2.Heap⼤⼩并不决定进程的内存使⽤量。进程的内存使⽤量要⼤于-Xmx定义的值,因为Java为其他任务分配内存,例如每个线程的Stack等。
2.Stack的设定
每个线程都有他⾃⼰的Stack。
Xss每个线程的Stack⼤⼩
Stack的⼤⼩限制着线程的数量。如果Stack过⼤就好导致内存溢漏。-Xss参数决定Stack⼤⼩,例如-Xss1024K。如果Stack太⼩,也会导致Stack溢漏。
3.硬件环境
硬件环境也影响GC的效率,例如机器的种类,内存,swap空间,和CPU的数量。
如果你的程序需要频繁创建很多transient对象,会导致JVM频繁GC。这种情况你可以增加机器的内存,来减少Swap空间的使⽤[2]。
4.4种GC
第⼀种为单线程GC,也是默认的GC。,该GC适⽤于单CPU机器。
第⼆种为ThroughputGC,是多线程的GC,适⽤于多CPU,使⽤⼤量线程的程序。第⼆种GC与第⼀种GC相似,不同在于GC在收集Young区是多线程的,但在Old区和第⼀种⼀样,仍然采⽤单线程。-XX:+UseParallelGC参数启动该GC。
第三种为ConcurrentLowPauseGC,类似于第⼀种,适⽤于多CPU,并要求缩短因GC造成程序停滞的时间。这种GC可以在Old区的回收同时,运⾏应⽤程序。-XX:+UseConcMarkSweepGC参数启动该GC。
第四种为IncrementalLowPauseGC,适⽤于要求缩短因GC造成程序停滞的时间。这种GC可以在Young区回收的同时,回收⼀部分Old区对象。-Xincgc参数启动该GC。
4种GC的具体描述参见[3]。关于JVM内存设置的内容就介绍到这⾥,请关注本节其他相关报道。
参考:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。