这里向你们描述一下如何使用Tomcat配置JVM参数,Tomcat自己不能直接在计算机上运行,须要依赖于硬件基础之上的操做系统和一个java虚拟机。您能够选择本身的须要选择不一样的操做系统和对应的JDK的版本,但仍是推荐您使用Sun公司发布的JDK。java
jvm在client模式,进行内存回收时,会停下全部的其它工做,带回收完毕才去执行其它任务,在这期间eclipse就卡住了。因此适当的增长jvm申请的内存大小来减小其回收的次数甚至不回收,就会是卡的现象有明显改善。程序员
主要经过如下的几个jvm参数来设置堆内存的:web
-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堆的最大值dom
这两个值的大小通常根据须要进行设置。初始化堆的大小执行了虚拟机在启动时向系统申请的内存的大小。通常而言,这个参数不重要。可是有的应用程序在大负载 的状况下会急剧地占用更多的内存,此时这个参数就是显得很是重要,若是虚拟机启动时设置使用的内存比较小而在这种状况下有许多对象进行初始化,虚拟机就必 须重复地增长内存来知足使用。eclipse
因为这种缘由,咱们通常把-Xms和-Xmx设为同样大,而堆的最大值受限于系统使用的物理内存。通常使用数据量较大的应用程序会使用持久对象,内存使用 有可能迅速地增加。当应用程序须要的内存超出堆的最大值时虚拟机就会提示内存溢出,而且致使应用服务崩溃。所以通常建议堆的最大值设置为可用内存的最大值 的80%。
Tomcat默承认以使用的内存为128MB,在较大型的应用项目中,这点内存是不够的,须要调大。
Windows下,在文件/bin/catalina.bat,Unix下,在文件/bin/catalina.sh的前面,增长以下设置:
JAVA_OPTS='-Xms【初始化内存大小】
-Xmx【可使用的最大内存】'
须要把这个两个参数值调大。例如:
表示初始化内存为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
-Xloggc:log/gc.log";
说明一下,-XX:SurvivorRatio=65536,-XX:MaxTenuringThreshold=0就是去掉了救助空间;
-Xnoclassgc禁用类垃圾回收,性能会高一点;
-XX:+DisableExplicitGC禁止System.gc(),省得程序员误调用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中,能够在startweblogic.cmd中对每一个domain虚拟内存的大小进行设置,默认的设置是在commEnv.cmd里面。简单介绍了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?有以下缘由:
◆程序内调用了System.gc()或Runtime.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内存设置的内容就介绍到这里,请关注本节其余相关报道。