您的位置:首页 > 编程语言 > Java开发

JVM参数调优八大技巧之笔记

2014-03-16 19:28 211 查看
 要想配置好JVM参数,需要对年轻代,年老代,救助空间和永久代有一定了解,还要了解jvm内存管理逻辑,最终还要根据自己的应用来做调整。

这里和大家分享一下JVM参数调优的八条经验,JVM参数调优,这是很头痛的问题,设置的不好,JVM不断执行FullGC,导致整个系统变得很慢,网站停滞时间能达10秒以上,相信通过本文的学习你对JVM参数调优有新的认识。

实例讲解JVM参数调优的八条经验

本文将介绍JVM参数调优,这是很头痛的问题,设置的不好,JVM不断执行FullGC,导致整个系统变得很慢,网站停滞时间能达10秒以上,这种情况如果没隔几分钟就来一次,自己都受不了。这种停滞在测试的时候看不出来,只有网站pv达到数十万/天的时候问题就暴露出来了。

要想配置好JVM参数,需要对年轻代、年老代、救助空间和永久代有一定了解,还要了解jvm内存管理逻辑,最终还要根据自己的应用来做调整。关于JVM参数上网一搜就能搜出一大把,也有很多提供实践的例子,我也按照各种例子测试过,最终还是会出现问题。

经过几个月的实践改善,我就网站(要求无停滞时间)的jvm参数调优给出以下几条经验。
    1.建议用64位操作系统,linux下64位的jdk比32位的jdk要慢一些,但是吃得内存更多,吞吐量更大。
    2.xMX和XMS设置一样大,MaxPermSize和MinPermSize设置一样大,这样可以减轻伸缩堆大小带来的压力。

    3.调试的时候设置一些打印jvm参数,这样可以从gc.log看出一些端倪出来。

    4.系统停顿的时候可能是GC的问题也可能是程序的问题,多用jmap和jstack查看,或者killall-3java,然后查看java控制台日志,

    能看出很多问题。有一次,网站突然很慢,jstack一看,原来是自己写的URLConnection连接太多没有释放,改一下程序就ok了。

    5.仔细了解自己的应用,如果用了缓存,那么年老代应该大一些,缓存的Hashmap不应该无限制长,建议采用LRU(近期最少使用算法)

     的map做缓存,lrumap的最大长度也要根据具体情况来看。

    6.不管怎样,永久代还是会逐渐变满,所以隔三差五重启java服务器是必要的,我每天都自动重启。

    7.采用并发回收时,年轻代少一点,年老代要大,因为年老大用的是并发回收,即使时间长点也不会影响其他程序继续运行,网站不会停顿。 

希望从JVM的角度 去解释 。

-Xms512m 堆的最小值 

-Xmx1024m 堆的最大值 

另外hotspot垃圾回收采用分代搜集的方法,把堆分为三个部分,新域,旧域和永久域。Jvm生成的所有新对象放在新域中。一旦对象经历了一定数量的垃圾收集循环后,便获得使用期并进入旧域。在永久域中jvm则存储class和method对象。就配置而言,永久域是一个独立域并且不认为是堆的一部分 

-XX:MaxPermSize=2设置永久域的最大值, 

-XX:PermSize=256M设置永久域的初始值

备注:

我的最终配置如下(系统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 j2ee jdk java