您的位置:首页 > 其它

JVM参数

2015-10-20 16:20 225 查看
JVM参数命令行选项主要有3类:标准选项、非标准选项和非稳定选项。

     标准选项是要求所有Java虚拟机都必须实现的选项。

     非标准选项(以-X为前缀)不保证、也不强制所有JVM实现都必须支持。

     非稳定选项(以-XX为前缀)通常是为了特定的需要而对JVM的运行进行校正,并且可能需要有系统配置参数的访问权限。

对于带有布尔标记的非稳定选项来说,选项名前的+或-表示true或false,用以开启或关闭特定的HotSpot VM特性或参数。

堆大小设置:

-Xmx3550m:设置JVM最大可用内存为3550M。

-Xms3550m:设置JVM初始内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。

-Xmn2g:设置年轻代大小为2G。整个堆大小 = 年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。-XX:NewSize=2g也一样效果。

-Xss128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。

-XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5。

-XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6。

-XX:MaxPermSize=16m:设置持久代大小为16m。

-XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概率。

回收器选择:

1.与串行(Serial)收集器相关:

-XX:+UseSerialGC:在新生代和老年代使用串行收集器。

2.与并行(ParNew)收集器相关:

-XX:+UseParNewGC:在新生代使用并行收集器,老年代使用串行回收器。

-XX:ParallelGCThreads=8:配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。年轻代的并行收集线程数默认是(ncpus <= 8) ? ncpus : 3 + ((ncpus * 5) / 8)。

3.与并行回收(Parallel Scavenge)收集器相关:

-XX:+UseParallelGC:新生代使用并行回收收集器。此配置仅对年轻代有效,此时老年代则默认使用串行收集器。

-XX:+UseParallelOldGC:指定新生代和老年代都使用并行回收收集器。

-XX:MaxGCPauseMillis=100:参数允许的值是一个大于0的毫秒数,收集器将尽可能地保证内存回收话费时间不超过设定值。收集器在工作时,会自动调整Java新生代大小,尽可能把停顿时间控制在设定值。如果希望减少停顿时间,而把此值设得很小,JVM会以牺牲吞吐量和新生代空间为代价来换取预期的停顿时间。

-XX:GCTimeRatio:设置吞吐量大小,参数的值应当是一个大于0且小于100的整数,也就是垃圾收集时间占总时间的比率。默认情况下值为99,表示不超过1/(1+99)=1%的时间用于垃圾收集。

-XX:+UseAdaptiveSizePolicy:设置此选项后,并行回收收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行回收收集器时打开,就不需要手工指定新生代大小、Eden与Survivor区的比例、晋升老年代对象年龄等细节参数了。

-XX:ParallelGCThreads=8:也可以用于设置此收集方式下垃圾回收的线程数量。

4.CMS(Concurrent Mark Sweep)收集器

整个收集过程:CMS initial-mark -> CMS-concurrent-mark -> CMS-concurrent-preclean -> CMS-remark -> CMS-concurrent-sweep -> CMS-concurrent-reset

-XX:+UseConcMarkSweepGC:设置年老代为并发收集。测试中配置这个以后,-XX:NewRatio=4的配置失效了,原因不明。所以,此时年轻代大小最好用-Xmn设置。最新的JVM版本,当使用-XX:+UseConcMarkSweepGC时,-XX:UseParNewGC会自动开启。因此,如果年轻代的并行GC不想开启,可以通过设置-XX:-UseParNewGC来关掉。

-XX:+UseParNewGC:设置年轻代为并行收集。可与CMS收集同时使用。

-XX:+UseCMSCompactAtFullCollection:打开对年老代的压缩。CMS是不会整理堆碎片的,因此为了防止堆碎片引起full gc,通过会开启CMS阶段进行合并碎片,开启这个选项一定程度上会影响性能,但是可以消除碎片,可以通过配置适当的CMSFullGCsBeforeCompaction来调整性能。

-XX:CMSFullGCsBeforeCompaction=5:由于并发收集器不对内存空间进行压缩、整理,所以运行一段时间以后会产生“碎片”,使得运行效率降低。此值设置运行多少次GC以后对内存空间进行压缩、整理。

-XX:+CMSConcurrentMTEnabled:当该标志被启用时,并发的CMS阶段将以多线程执行(因此,多个GC线程会与所有的应用程序线程并行工作)。该标志已经默认开启,如果顺序执行更好,这取决于所使用的硬件,多线程执行可以通过-XX:-CMSConcurremntMTEnabled禁用。

-XX:ConcGCThreads

       标志-XX:ConcGCThreads=<value>定义并发CMS过程运行时的线程数。比如value=4意味着CMS周期的所有阶段都以4个线程来执行。尽管更多的线程会加快并发CMS过程,但其也会带来额外的同步开销。因此,对于特定的应用程序,应该通过测试来判断增加CMS线程数是否真的能够带来性能的提升。

       如果还标志未设置,JVM会根据并行收集器中的-XX:ParallelGCThreads参数的值来计算出默认的并行CMS线程数。该公式是ConcGCThreads = (ParallelGCThreads + 3)/4。因此,对于CMS收集器,-XX:ParallelGCThreads标志不仅影响“stop-the-world”垃圾收集阶段,还影响并发阶段。

       建议第一次运行CMS收集器时使用其默认设置, 然后如果需要调优再进行测试。只有在生产系统中测量(或类生产测试系统)发现应用程序的暂停时间的目标没有达到 , 就可以通过这些标志应该进行GC调优。

-XX:CMSInitiatingOccupancyFraction -XX:+UseCMSInitiatingOccupancyOnly

       当堆满之后,并行收集器便开始进行垃圾收集,例如,当没有足够的空间来容纳新分配或提升的对象。对于CMS收集器,长时间等待是不可取的,因为在并发垃圾收集期间应用持续在运行(并且分配对象)。因此,为了在应用程序使用完内存之前完成垃圾收集周期,CMS收集器要比并行收集器更先启动。

       因为不同的应用会有不同对象分配模式,JVM会收集实际的对象分配(和释放)的运行时数据,并且分析这些数据,来决定什么时候启动一次CMS垃圾收集周期。为了引导这一过程, JVM会在一开始执行CMS周期前作一些线索查找。该线索由 -XX:CMSInitiatingOccupancyFraction=<value>来设置,该值代表老年代堆空间的使用率。比如,value=75意味着第一次CMS垃圾收集会在老年代被占用75%时被触发。通常CMSInitiatingOccupancyFraction的默认值为68。

       用-XX+UseCMSInitiatingOccupancyOnly标志来命令JVM不基于运行时收集的数据来启动CMS垃圾收集周期,而是通过CMSInitiatingOccupancyFraction的值进行每一次CMS收集,而不仅仅是第一次。然而,请记住大多数情况下,JVM比我们自己能作出更好的垃圾收集决策。因此,只有当我们充足的理由并且对应用程序产生的对象的生命周期有深刻的认知时,才应该使用该标志。

-XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled

       相对于并行收集器,CMS收集器默认不会对永久代进行垃圾回收。如果希望对永久代进行垃圾回收,可用设置标志-XX:+CMSClassUnloadingEnabled。在早期JVM版本中,要求设置额外的标志-XX:+CMSPermGenSweepingEnabled。注意,即使没有设置这个标志,一旦永久代耗尽空间也会尝试进行垃圾回收,但是收集不会是并行的,而再一次进行Full GC。

-XX:+CMSParallelRemarkEnabled

      为了减少第二次暂停的时间,开启并行remark。如果remark还是过长的话,可以开启-XX:+CMSScavengeBeforeRemark 选项,强制remark之前开始一次minor gc,减少remark的暂停时间(因为remark标记的是最近修改的内容,最近变化的内容往往在Young区),但是在remark之后也将立即开始又一次minor gc。

辅助配置:

-verbose:gc -XX:+PrintGC -XX:+PrintGCDetails

-XX:+Printetails

-XX:+PrintGCTimeStamps

-XX:+PrintGCApplicationConcurrentTime:打印每次垃圾回收前,程序未中断的执行时间。

-XX:+PrintGCApplicationStoppedTime:打印垃圾回收期间程序暂停的时间。

-XX:PrintHeapAtGC:打印GC前后的详细堆栈信息

-Xloggc:filename

两种fail引起full gc :Prommotion failed和Concurrent mode failed。

     这个问题的产生是由于Survivor空间不够,从而向年老代转移对象,年老代没有足够的空间来容纳这些对象,导致一次full gc的产生。

     解决这个问题的办法有两种完全相反的倾向:增大Survivor空间、增大年老代或者去掉Survivor空间。

     增大Survivor空间就是调整-XX:SurvivorRatio参数,这个参数是Eden区和Survivor区的大小比值,默认是32,也就是说Eden区是Survivor区的32倍大小,要注意Survivo是有两个区的,因此Surivivor其实占整个young genertation的1/34。调小这个参数将增大survivor区,让对象尽量在survitor区呆长一点,减少进入年老代的对象。

     去掉Survivor空间的想法是让大部分不能马上回收的数据尽快进入年老代,加快年老代的回收频率,减少年老代暴涨的可能性,这个是通过将-XX:SurvivorRatio 设置成比较大的值(比如65536)来做到。在我们的应用中,将young generation设置成256M,这个值相对来说比较大了,而Survivor空间设置成默认大小(1/34),从压测情况来看,没有出现prommotion failed的现象,年轻代比较大,从GC日志来看,minor gc的时间也在5-20毫秒内,还可以接受,因此暂不调整。

      Concurrent mode failed的产生是由于CMS回收年老代的速度太慢,导致年老代在CMS完成前就被占满,引起full gc,避免这个现象的产生就是调小-XX:CMSInitiatingOccupancyFraction参数的值,让CMS更早更频繁的触发,降低年老代被占满的可能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: