jvm学习 - 虚拟机启动常用参数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jvm学习 - 虚拟机启动常用参数相关的知识,希望对你有一定的参考价值。

介绍

原文地址:1

在启动虚拟机时,可以通过配置不同参数来自定义自己的内存相关信息。

注:以下参数都是直接举例使用,可以通过修改后面的数字和单位直接使用。

参数名称 含义 默认值 使用方式 描述
-Xms 初始堆大小 物理内存的1/64(<1GB) -Xms=2048m 默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制.
-Xmx 最大堆大小 物理内存的1/4(<1GB) -Xmx=4096m 默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制
-Xmn 年轻代大小   -Xmn=1024m 此处的大小是(eden+ 2 survivor space).与jmap -heap中显示的New gen是不同的。
整个堆大小=年轻代大小 + 年老代大小 + 持久代大小.
增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8
-XX:+HeapDumpOnOutOfMemoryError     -XX:+HeapDumpOnOutOfMemoryError 在虚拟机发生内存溢出异常时,dump出当前的内存堆转储快照,以便后续分析异常
-XX:NewSize 设置年轻代大小(for 1.3/1.4)   -XX:NewSize = 512M  
-XX:MaxNewSize 设置年轻代最大值(for 1.3/1.4)   -XX:MaxNewSize = 1024M JVM堆区域新生代内存的最大可分配大小(PermSize不属于堆区), 生产环境建议设为800M-1024M
-XX:PermSize 设置持久代(perm gen)初始值 物理内存的1/64 -XX:PermSize = 512M JVM初始分配的非堆内存, 不会被回收, 生产环境建议与maxPermSize相同, 设为256m以上
-XX:MaxPermSize 设置持久代最大值 物理内存的1/4 -XX:PermSize = 512M  
-Xss 每个线程的堆栈大小   -Xss = 256K

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

-XX:ThreadStackSize Thread Stack Size   -XX:ThreadStackSize = 1024 线程栈深度(0 means use default stack size) [Sparc: 512; Solaris x86: 320 (was 256 prior in 5.0 and earlier); Sparc 64 bit: 1024; Linux amd64: 1024 (was 0 in 5.0 and earlier); all others 0.]
 -XX:NewRatio  年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)     -XX:NewRatio=4  -XX:NewRatio=4表示年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5
Xms=Xmx并且设置了Xmn的情况下,该参数不需要进行设置
 -XX:SurvivorRatio  Eden区与Survivor区的大小比值     -XX:SurvivorRatio = 8  设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10
 -XX:MaxTenuringThreshold  垃圾最大年龄    -XX:MaxTenuringThreshold = 0  如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代. 对于年老代比较多的应用,可以提高效率.如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活 时间,增加在年轻代即被回收的概率
该参数只有在串行GC时才有效.
 -XX:PretenureSizeThreshold  对象超过多大是直接在旧生代分配    -XX:PretenureSizeThreshold = 2M  单位字节 新生代采用Parallel Scavenge GC时无效
另一种直接在旧生代分配的情况是大的数组对象,且数组中无外部引用对象.
垃圾回收器参数         
 -XX:+UseParallelGC  Full GC采用parallel MSC
(此项待验证)
     选择垃圾收集器为并行收集器.此配置仅对年轻代有效.即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集.(此项待验证)
 -XX:+UseParNewGC  设置年轻代为并行收集      可与CMS收集同时使用
JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此值
 -XX:ParallelGCThreads  并行收集器的线程数      此值最好配置与处理器数目相等 同样适用于CMS
 -XX:+UseParallelOldGC  年老代垃圾收集方式为并行收集(Parallel Compacting)      
 -XX:MaxGCPauseMillis  每次年轻代垃圾回收的最长时间(最大暂停时间)      如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值.
 -XX:+UseAdaptiveSizePolicy  自动选择年轻代区大小和相应的Survivor区比例      设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行收集器时,一直打开
 -XX:GCTimeRatio  设置垃圾回收时间占程序运行时间的百分比      公式为1/(1+n)
 -XX:+ScavengeBeforeFullGC  Full GC前调用YGC      
 -XX:+UseConcMarkSweepGC  使用CMS内存收集      测试中配置这个以后,-XX:NewRatio=4的配置失效了,原因不明.所以,此时年轻代大小最好用-Xmn设置.???
 -XX:+PrintGCDetails        输出形式:[GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs]
[GC [DefNew: 8614K->8614K(9088K), 0.0000665 secs][Tenured: 112761K->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs]
 -XX:+PrintGC        

输出形式:

[GC 118250K->113543K(130112K), 0.0094143 secs]
[Full GC 121376K->10414K(130112K), 0.0650971 secs]

建议

    1. 年轻代大小选择
      • 响应时间优先的应用:尽可能设大,直到接近系统的最低响应时间限制(根据实际情况选择).在此种情况下,年轻代收集发生的频率也是最小的.同时,减少到达年老代的对象.
      • 吞吐量优先的应用:尽可能的设置大,可能到达Gbit的程度.因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用.
      • 避免设置过小.当新生代设置过小时会导致:1.YGC次数更加频繁 2.可能导致YGC对象直接进入旧生代,如果此时旧生代满了,会触发FGC.
    2. 年老代大小选择
      1. 响应时间优先的应用:年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数.如果堆设置小了,可以会造成内存碎 片,高回收频率以及应用暂停而使用传统的标记清除方式;如果堆大了,则需要较长的收集时间.最优化的方案,一般需要参考以下数据获得:
        并发垃圾收集信息、持久代并发收集次数、传统GC信息、花在年轻代和年老代回收上的时间比例。
      2. 吞吐量优先的应用:一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代.原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而年老代尽存放长期存活对象.
    3. 较小堆引起的碎片问题
      因为年老代的并发收集器使用标记,清除算法,所以不会对堆进行压缩.当收集器回收时,他会把相邻的空间进行合并,这样可以分配给较大的对象.但是,当堆空间较小时,运行一段时间以后,就会出现"碎片",如果并发收集器找不到足够的空间,那么并发收集器将会停止,然后使用传统的标记,清除方式进行回收.如果出现"碎片",可能需要进行如下配置:
      -XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩.
      -XX:CMSFullGCsBeforeCompaction=0:上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩
    4. 用64位操作系统,Linux下64位的jdk比32位jdk要慢一些,但是吃得内存更多,吞吐量更大
    5. XMX和XMS设置一样大,MaxPermSize和MinPermSize设置一样大,这样可以减轻伸缩堆大小带来的压力
    6. 使用CMS的好处是用尽量少的新生代,经验值是128M-256M, 然后老生代利用CMS并行收集, 这样能保证系统低延迟的吞吐效率。 实际上cms的收集停顿时间非常的短,2G的内存, 大约20-80ms的应用程序停顿时间
    7. 系统停顿的时候可能是GC的问题也可能是程序的问题,多用jmap和jstack查看,或者killall -3 java,然后查看java控制台日志,能看出很多问题。(相关工具的使用方法将在后面的blog中介绍)
    8. 仔细了解自己的应用,如果用了缓存,那么年老代应该大一些,缓存的HashMap不应该无限制长,建议采用LRU算法的Map做缓存,LRUMap的最大长度也要根据实际情况设定。
    9. 采用并发回收时,年轻代小一点,年老代要大,因为年老大用的是并发回收,即使时间长点也不会影响其他程序继续运行,网站不会停顿
    10. JVM参数的设置(特别是 –Xmx –Xms –Xmn -XX:SurvivorRatio  -XX:MaxTenuringThreshold等参数的设置没有一个固定的公式,需要根据PV old区实际数据 YGC次数等多方面来衡量。为了避免promotion faild可能会导致xmn设置偏小,也意味着YGC的次数会增多,处理并发访问的能力下降等问题。每个参数的调整都需要经过详细的性能测试,才能找到特定应用的最佳配置        

以上是关于jvm学习 - 虚拟机启动常用参数的主要内容,如果未能解决你的问题,请参考以下文章

Java虚拟机详解03----常用JVM配置参数

Java虚拟机详解----常用JVM配置参数

java虚拟机常用的jvm配置参数

深入理解JVM虚拟机10:JVM常用参数以及调优实践

JVM虚拟机---常用JVM配置参数

第八章:JVM常用操作参数