zoukankan      html  css  js  c++  java
  • JVM 参数优化

    1. 参数分类

      1. 标准参数 

        功能和输出的参数都是很稳定的 在未来的JVM版本中不会改变 可以使用java -help检索出所有的标准参数

      2. X参数  

        非标准化参数 在未来的版本可能会改变 所有的参数都用-X开始 可以使用java -X检索 

      3. XX参数  

        非标准 用于JVM开发的debug和调优

           配置说明:

              所有的XX参数都以”-XX:”开始,但是随后的语法不同,取决于参数的类型。

              对于布尔类型的参数,我们有”+”或”-“,然后才设置JVM选项的实际名称。例如,-XX:+<name>用于激活<name>选项,而-XX:-<name>用于注销选项。

              对于需要非布尔值的参数,如string或者integer,我们先写参数的名称,后面加上”=”,最后赋值。例如, -XX:<name>=<value>给<name>赋值<value>。

     

     2. HotSpot JVM类型

    a ) server

    默认为堆提供了一个更大的空间和并行的垃圾收集器 并且在运行时可以更大程度的优化代码

    b ) client

    客户端虚拟机有较小的默认堆内存 可以缩短JVM启动的时间和占用更少的内存 客户端的JVM只有在32位操作系统中才有

    注意 

    1 ) 从JDK5开始 当应用启动时会检测当前的运行环境是否是服务器 如果是服务器就使用Server JVM 这是为了提升性能,一般来说Server JVM启动比Client JVM慢,

         原因是使用的是重量级的虚拟机,但是内部进行了很多优化,而Client JVM使用的是轻量级的JVM,当服务稳定运行后还是Server JVM的速度更快一些。

    2 ) 在JDK6中 Server JVM要求至少双核CPU和2GB物理内存

    3 ) 在32位操作系统上 JDK可以运行Server JVM 但是JRE只能运行Client JVM

    3. 常见参数说明

    3.1 内存管理参数

    • -Xms 和 -Xmx (-XX:InitialHeapSize 和  -XX:MaxHeapSize)
      1 )  -Xms 和 -XX:InitialHeapSize
            -Xms是 -XX:InitialHeapSize的简写 表示的是初始化堆的大小
      2 ) -Xmx 和 -XX:MaxHeapSize
           -Xmx 是 -XX:MaxHeapSize的简写 表示的是设置堆的最大大小
    • -XX:+HeapDumpOnOutOfMemoryError 和 -XX:HeapDumpPath
       1 )  -XX:+HeapDumpOnOutOfMemoryError:
             使得JVM在产生内存溢出时自动生成堆内存快照
      2 ) XX:HeapDumpPath=<path>
             改变默认的堆内存快照生成路径,<path>可以是相对或者绝对路径

    •  -XX:OnOutOfMemoryError
        当内存发生溢出时 执行一串指令


      eg: java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/dump001.hprof -XX:OnOutOfMemoryError ="./dump.sh" ...

     

    • -XX:PermSize和-XX:MaxPermSize
      1 ) -XX:PermSize:设置永久代的初始大小
      2 ) -XX:MaxPermSize:设置永久代的最大大小

      eg: java -XX:PermSize=128m -XX:MaxPermSize=256m ...

    • 从JDK8开始,永久代(PermGen)被废弃,取而代之的是一个称为Metaspace的存储空间。Metaspace使用的是本地内存,而不是堆内存,也就是说在默认情况下Metaspace
      的大小只与本地内存大小有关。也可以通过以下的参数对Metaspace进行配置:
      1. -XX:MetaspaceSize=N 
        这个参数是初始化的Metaspace大小,该值越大触发Metaspace GC的时机就越晚。随着GC的到来,虚拟机会根据实际情况调控Metaspace的大小,可能增加上限也可能降低。

      2. -XX:MaxMetaspaceSize=N 
        这个参数用于限制Metaspace增长的上限,防止因为某些情况导致Metaspace无限的使用本地内存,影响到其他程序。在本机上该参数的默认值为4294967295B(大约4096MB)。

      3. -XX:MinMetaspaceFreeRatio=N 
        当进行过Metaspace GC之后,会计算当前Metaspace的空闲空间比,如果空闲比小于这个参数,那么虚拟机将增长Metaspace的大小。在本机该参数的默认值为40,也就是40%。

        设置该参数可以控制Metaspace的增长的速度,太小的值会导致Metaspace增长的缓慢,Metaspace的使用逐渐趋于饱和,可能会影响之后类的加载。而太大的值会导致Metaspace增长的过快,浪费内存。

      4. -XX:MaxMetasaceFreeRatio=N 
        当进行过Metaspace GC之后, 会计算当前Metaspace的空闲空间比,如果空闲比大于这个参数,那么虚拟机会释放Metaspace的部分空间。在本机该参数的默认值为70,也就是70%。

      5. -XX:MaxMetaspaceExpansion=N 
        Metaspace增长时的最大幅度。在本机上该参数的默认值为5452592B(大约为5MB)。

      6. -XX:MinMetaspaceExpansion=N 
        Metaspace增长时的最小幅度。在本机上该参数的默认值为340784B(大约330KB为)。

    3.2 新生代垃圾回收

    • -XX:NewSize和-XX:MaxNewSize
      1 ) -XX:NewSize 设置新生代的初始大小
      2 ) -XX:MaxNewSize 设置新生代的最大大小 
      注意:
          新生代只是堆的一部分 新生代越大老年代越小。一般不允许新生代比老年代还大,考虑到GC最坏的情况新生代全部复制到老年代会产生OOM错误,
          一般最大设置为-Xmx/2[堆大小的一半]。
    • -XX:NewRatio
      设置新生代和老年代的相对大小。优点是新生代大小会随着整个堆大小动态扩展。 
      eg:-XX:NewRatio=3[老年代/新生代=3]
    • -XX:SurvivorRatio
      指定Eden区和Survivor区的大小比例 ( 注意两个survivor区是一样大的) 
      eg: -XX:SurvivorRatio=10  // 表示Eden区占整个新生代的10/12 每个Survivor占1/12
      注意:
          Survior区过大 虽然有足够的空间容纳GC后的幸存对象,但是Eden区有效会导致空间很快耗尽 增加minorGC次数
          Survior区过小 没有足够的空间容纳GC后的幸存对象 使得对象都会移动到老年代 不易回收
    • -XX:+PrintTenuringDistribution
      指定JVM在每次新生代GC时,输出Survivor中对象的年龄分布.
    • -XX:InitialTenuringThreshold、-XX:MaxTenuringThreshold 和 -XX:TargetSurvivorRatio
       -XX:InitialTenuringThreshold 设置老年代阈值的初始值
       -XX:MaxTenuringThreshold 设置老年代阈值的最大值
       -XX:TargetSurvivorRatio 设置幸存区的目标使用率

    3.3 收集器参数

    • -XX:+UseSerialGC
      激活串行垃圾收集器。例如单线程面向吞吐量的垃圾收集器,推荐用于只有单个CPU的JVM。
    • -XX:+UseParallelGC
      使用多线程并行执行年轻代垃圾收集
    • -XX:+UseParallelOldG
      除了激活年轻代并行垃圾收集,也激活了年老代并行垃圾收集。
    • -XX:ParallelGCThreads
      -XX:ParallelGCThreads=<value> 指定并行垃圾收集的线程数量
    • -XX:-UseAdaptiveSizePolicy
      垃圾收集器能将堆大小动态变动像GC设置一样应用到不同的堆区域,只要有证据表明这些变动将能提高GC性能。
    • -XX:GCTimeRatio
      -XX:GCTimeRatio=<value>指定JVM吞吐量要达到的目标值 
      指定目标应用程序线程的执行时间和总的程序执行时间达到N/(N+1)的目标比值 (-XX:GCTimeRatio的默认值是99,
      也就是说,应用程序线程应该运行至少99%的总执行时间)。
      eg: -XX:GCTimeRatio=9 // 要求应用程序线程在整个执行时间中至少9/10是活动的(因此,GC线程占用其余1/10)
    • -XX:MaxGCPauseMillis
      通过-XX:GCTimeRatio=<value>告诉JVM最大暂停时间目标值[ms为单位]

    3.4 CMS收集器

    并发标记清理收集器CMS收集器:低应用停顿时间 

    • -XX:+UseConcMarkSweepGC
      激活CMS收集器,JVM默认使用的是并行处理器。
    • -XX:UseParNewGC
      使用CMS收集器时,激活年轻代使用多线程并行执行垃圾回收 
      注意:
          最新的JVM版本,当使用-XX:+UseConcMarkSweepGC时,-XX:UseParNewGC会自动开启。 
          因此,如果年轻代的并行GC不想开启,可以通过设置-XX:-UseParNewGC来关掉。
    • -XX:+CMSConcurrentMTEnabled
      并发的CMS阶段以多线程执行 默认开启
    • -XX:ConcGCThreads
      -XX:ConcGCThreads=<value>定义并发CMS中运行的线程数 
      注意:
          如果还标志未设置,JVM会根据并行收集器中的-XX:ParallelGCThreads参数的值来计算出默认的并行CMS线程数。
          该公式是ConcGCThreads = (ParallelGCThreads + 3)/4。
          因此,对于CMS收集器,-XX:ParallelGCThreads标志不仅影响“stop-the-world”垃圾收集阶段,还影响并发阶段。
    • -XX:CMSInitiatingOccupancyFraction
      该值代表老年代堆空间的使用率。比如,value=75意味着第一次CMS垃圾收集会在老年代被占用75%时被触发。
      通常CMSInitiatingOccupancyFraction的默认值为68(之前很长时间的经历来决定的)。
    • -XX:+UseCMSInitiatingOccupancyOnly
      命令JVM不基于运行时收集的数据来启动CMS垃圾收集周期。 
      注意:
          JVM通过CMSInitiatingOccupancyFraction的值进行每一次CMS收集,而不仅仅是第一次。
    • -XX:+CMSClassUnloadingEnabled
      CMS默认不会对永久代进行垃圾回收,如果希望对永久代进行垃圾回收可以设置此标志。 
      注意:
          即使没有设置这个标志,一旦永久代耗尽空间也会尝试进行垃圾回收,但是收集不会是并行的,而再一次进行Full GC。
    • -XX:+CMSIncrementalMode
      开启CMS收集器的增量模式( 增量模式会经常暂停CMS过程,以便对应用程序作出完全的让步)。
    • -XX:+ExplicitGCInvokesConcurrent和-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses
      1)-XX:+ExplicitGCInvokesConcurrent
           命令JVM无论什么时候调用系统GC,都执行CMS GC,而不是Full GC
      2)-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses
           保证当有系统GC调用时,永久代也被包括进CMS垃圾回收的范围内。因此,通过使用这些标志,我们可以防止出现意料之外的”stop-the-world”的系统GC。
    • -XX:+DisableExplicitGC
      该标志将告诉JVM完全忽略系统的GC调用(不管使用的收集器是什么类型)

    3.5 GC日志

    • -XX:+PrintGC
      开启简单GC日志模式 为每一次新生代的GC和每一次Full GC打印一行信息
    • -XX:PrintGCDetails
      开启了详细GC日志模式 此模式下的日志格式和GC算法有关 
    • -XX:+PrintGCTimeStamps和-XX:+PrintGCDateStamps
      1)-XX:+PrintGCTimeStamps
          可以将时间和日期也加到GC日志中。表示自JVM启动至今的时间戳
      2)-XX:+PrintGCDateStamps
           每一行添加绝对的日期和时间。
    • -Xloggc
      缺省的GC日志时输出到终端的,使用-Xloggc:也可以输出到指定的文件。
      需要注意这个参数隐式的设置了参数-XX:+PrintGC和-XX:+PrintGCTimeStamps,但为了以防在新版本的JVM中有任何变化,建议显示的设置这些参数。

     

    4 推荐配置

    -server
    -XX:+AggressiveOpts  
    # 内存 
    -Xmx 2048m
    -Xms 2048m
    -Xmn 683m   #为 堆内存的 1/3
    -XX:PermSize=128m 
    -XX:LargePageSizeInBytes=128m 

    # cms相关优化
    -XX:+UseCMSInitiatingOccupancyOnly 
    -XX:+CMSParallelRemarkEnabled 

    # gc相关
    -XX:+DisableExplicitGC 
    -XX:+PrintGCDateStamps
    -XX:+UseCMSCompactAtFullCollection 
    -XX:CMSInitiatingOccupancyFraction=70
    -XX:+UseConcMarkSweepGC 

    #other
    -XX:-UseFastAccessorMethods 

     

    5 备注

     

    功能开关: 

     

    参数 

    默认值或限制 

    说明 

    参数 

    默认值 

    功能 

    -XX:-AllowUserSignalHandlers 

    限于Linux和Solaris,默认不启用 

    允许为java进程安装信号处理器,信号处理参见类:sun.misc.Signal, sun.misc.SignalHandler 

    -XX:+DisableExplicitGC 

    默认启用 

    禁止在运行期显式地调用System.gc() 

    -XX:+FailOverToOldVerifier 

    Java6新引入选项,默认启用 

    如果新的Class校验器检查失败,则使用老的校验器(失败原因:因为JDK6最高向下兼容到JDK1.2,而JDK1.2的class info 与JDK6的info存在较大的差异,

    所以新校验器可能会出现校验失败的情况) 

    -XX:+HandlePromotionFailure 

    java5以前是默认不启用,java6默认启用 

    关闭新生代收集担保 

    -XX:+MaxFDLimit 

    限于Solaris,默认启用 

    设置java进程可用文件描述符为操作系统允许的最大值。 

    -XX:PreBlockSpin=10 

    -XX:+UseSpinning 必须先启用,对于java6来说已经默认启用了,这里默认自旋10次 

    控制多线程自旋锁优化的自旋次数 

    -XX:-RelaxAccessControlCheck 

    默认不启用 

    在Class校验器中,放松对访问控制的检查,作用与reflection里的setAccessible类似 

    -XX:+ScavengeBeforeFullGC 

    默认启用 

    在Full GC前触发一次Minor GC 

    -XX:+UseAltSigs 

    限于Solaris,默认启用 

    为了防止与其他发送信号的应用程序冲突,允许使用候补信号替代 SIGUSR1和SIGUSR2 

    -XX:+UseBoundThreads 

    限于Solaris, 默认启用 

    绑定所有的用户线程到内核线程, 减少线程进入饥饿状态(得不到任何cpu time)的次数 

    -XX:-UseConcMarkSweepGC 

    默认不启用 

    启用CMS低停顿垃圾收集器,减少FGC的暂停时间 

    -XX:+UseGCOverheadLimit 

    默认启用 

    限制GC的运行时间。如果GC耗时过长,就抛OOM 

    -XX:+UseLWPSynchronization 

    限于solaris,默认启用 

    使用轻量级进程(内核线程)替换线程同步 

    -XX:-UseParallelGC 

    -server时启用,其他情况下,默认不启用 

    策略为新生代使用并行清除,年老代使用单线程Mark-Sweep-Compact的垃圾收集器 

    -XX:-UseParallelOldGC 

    默认不启用 

    策略为老年代和新生代都使用并行清除的垃圾收集器 

    -XX:-UseSerialGC 

    -client时启用,其他情况下,默认不启用 

    使用串行垃圾收集器 

    -XX:-UseSpinning 

    java1.4.2和1.5需要手动启用, java6默认已启用 

    启用多线程自旋锁优化 

    -XX:+UseTLAB 

    1.4.2以前和使用-client选项时,默认不启用,其余版本默认启用 

    启用线程本地缓存区 

    -XX:+UseSplitVerifier 

    java5默认不启用, java6默认启用 

    使用新的Class类型校验器 

    -XX:+UseThreadPriorities 

    默认启用 

    使用本地线程的优先级 

    -XX:+UseVMInterruptibleIO 

    限于solaris,默认启用 

    在solaris中,允许运行时中断线程 

     

    性能参数: 

     

    参数 

    默认值或限制 

    说明 

    -XX:+AggressiveOpts 

    JDK 5 update 6后引入,但需要手动启用, JDK6默认启用 

    启用JVM开发团队最新的调优成果。例如编译优化,偏向锁,并行年老代收集等 

    -XX:CompileThreshold=10000 

    1000 

    通过JIT编译器,将方法编译成机器码的触发阀值,可以理解为调用方法的次数,例如调1000次,将方法编译为机器码 

    -XX:LargePageSizeInBytes=4m 

    默认4m, amd64位:2m 

    设置堆内存的内存页大小 

    -XX:MaxHeapFreeRatio=70 

    70 

    GC后,如果发现空闲堆内存占到整个预估上限值的70%,则收缩预估上限值 

    -XX:MaxNewSize=size 

    1.3.1 Sparc: 32m, 1.3.1 x86: 2.5m 

    新生代占整个堆内存的最大值 

    -XX:MaxPermSize=64m 

    5.0以后: 64 bit VMs会增大预设值的30%, 1.4 amd64: 96m, 1.3.1 -client: 32m, 其他默认 64m 

    Perm(俗称方法区)占整个堆内存的最大值 

    -XX:MinHeapFreeRatio=40 

    40 

    GC后,如果发现空闲堆内存占到整个预估上限值的40%,则增大上限值 

    -XX:NewRatio=2 

    Sparc -client: 8, x86 -server: 8, x86 -client: 12, -client: 4 (1.3), 

    8 (1.3.1+), x86: 12, 其他默认 2 

    新生代和年老代的堆内存占用比例, 例如2表示新生代占年老代的1/2,占整个堆内存的1/3 

    -XX:NewSize=2.125m 

    5.0以后: 64 bit Vms 会增大预设值的30%, x86: 1m, x86, 5.0以后: 640k, 其他默认 2.125m 

    新生代预估上限的默认值 

    -XX:ReservedCodeCacheSize=32m 

    Solaris 64-bit, amd64, -server x86: 48m, 1.5.0_06之前, Solaris 64-bit amd64: 1024m, 其他默认 32m 

    设置代码缓存的最大值,编译时用 

    -XX:SurvivorRatio=8 

    Solaris amd64: 6, Sparc in 1.3.1: 25, Solaris platforms 5.0以前: 32, 其他默认 8 

    Eden与Survivor的占用比例。例如8表示,一个survivor区占用 1/8 的Eden内存,即1/10的新生代内存,为什么不是1/9? 

    因为我们的新生代有2个survivor,即S0和S1。所以survivor总共是占用新生代内存的 2/10,Eden与新生代的占比则为 8/10 

    -XX:TargetSurvivorRatio=50 

    50 

    实际使用的survivor空间大小占比。默认是50%,最高90% 

    -XX:ThreadStackSize=512 

    Sparc: 512, Solaris x86: 320 (5.0以前 256), Sparc 64 bit: 1024, Linux amd64: 1024 (5.0 以前 0), 其他默认 512. 

    线程堆栈大小 

    -XX:+UseBiasedLocking 

    JDK 5 update 6后引入,但需要手动启用, JDK6默认启用 

    启用偏向锁 

    -XX:+UseFastAccessorMethods 

    默认启用 

    优化原始类型的getter方法性能(get/set:Primitive Type) 

    -XX:-UseISM 

    默认启用 

    启用solaris的ISM 

    -XX:+UseLargePages 

    JDK 5 update 5后引入,但需要手动启用, JDK6默认启用 

    启用大内存分页 

    -XX:+UseMPSS 

    1.4.1 之前: 不启用, 其余版本默认启用 

    启用solaris的MPSS,不能与ISM同时使用 

    -XX:+UseStringCache 

    默认开启 

    启用缓存常用的字符串。 

    -XX:AllocatePrefetchLines=1 

    1 

    Number of cache lines to load after the last object allocation using prefetch instructions generated in JIT compiled code.

    Default values are 1 if the last allocated object was an instance and 3 if it was an array. 

    -XX:AllocatePrefetchStyle=1 

    1 

    Generated code style for prefetch instructions. 

    0 – no prefetch instructions are generate*d*, 

    1 – execute prefetch instructions after each allocation, 

    2 – use TLAB allocation watermark pointer to gate when prefetch instructions are executed. 

    -XX:+UseCompressedStrings 

    Java 6 update 21有一选项 

    其中,对于不需要16位字符的字符串,可以使用byte[] 而非char[]。对于许多应用,这可以节省内存,但速度较慢(5%-10%) 

    -XX:+OptimizeStringConcat 

    在Java 6更新20中引入 

    优化字符串连接操作在可能的情况下 

     

    调试参数: 

     

    参数 

    默认值或限制 

    说明 

    -XX:-CITime 

     

    打印发费在JIT编译上的时间 

    -XX:ErrorFile=./hs_err_pid<pid>.log 

    JDK6中引入 

    错误文件 

    -XX:-ExtendedDTraceProbes 

    JDK6中引入仅在Solaris 

    启用性能的影响DTrace探测器 

    -XX:HeapDumpPath=./java_pid<pid>.hprof 

    1.4.2 update 12, 5.0 update 7 

    指定HeapDump的文件路径或目录 

    -XX:-HeapDumpOnOutOfMemoryError 

    1.4.2 update 12, 5.0 update 7 

    当抛出OOM时进行HeapDump 

    -XX:OnError=”<cmd args>;<cmd args>” 

    1.4.2 update 9 

    当发生错误时执行用户指定的命令 

    -XX:OnOutOfMemoryError=”<cmd args>; 

    <cmd args>” 

    1.4.2 update 12, 6 

    当发生OOM时执行用户指定的命令 

    -XX:-PrintClassHistogram 

    1.4.2 

    当Ctrl+Break发生时打印Class实例信息,与jmap -histo相同 

    -XX:-PrintConcurrentLocks 

    6 

    当Ctrl+Break发生时打印java.util.concurrent的锁信息, 与jstack -l相同 

    -XX:-PrintCommandLineFlags 

    5 

    打印命令行上的标记 

    -XX:-PrintCompilation 

     

    当方法被编译时打印信息 

    -XX:-PrintGC 

     

    当GC发生时打印信息 

    -XX:-PrintGCDetails 

    1.4.0 

    打印GC详细信息 

    -XX:-PrintGCTimeStamps 

    1.4.0 

    打印GC用时 

    -XX:-PrintTenuringDistribution 

     

    打印Tenuring年龄信息 

    -XX:-TraceClassLoading 

     

    跟踪类加载 

    -XX:-TraceClassLoadingPreorder 

    1.4.2 

    跟踪所有加载的引用类 

    -XX:-TraceClassResolution 

    1.4.2 

    跟踪常量池的变化 

    -XX:-TraceClassUnloading 

     

    跟踪类的卸载 

    -XX:-TraceLoaderConstraints 

    6 

    Trace recording of loader constraints 

    -XX:+PerfSaveDataToFile 

     

    退出时保存jvmstat二进制文件 

    -XX:ParallelGCThreads= 

     

    设置新生代与老年代并行垃圾回收器的线程数 

    -XX:+UseCompressedOops 

     

    Enables the use of compressed pointers (object references represented as 32 bit offsets instead of 64-bit pointers) for optimized 64-bit performance with Java heap sizes less than 32gb. 

    -XX:+AlwaysPreTouch 

     

    Pre-touch the Java heap during JVM initialization. Every page of the heap is thus demand-zeroed during initialization rather than incrementally during application execution. 

    -XX:AllocatePrefetchDistance= 

     

    Sets the prefetch distance for object allocation. Memory about to be written with the value of new objects is prefetched into cache at this distance (in bytes) beyond the address of the last allocated object.

    Each Java thread has its own allocation point. The default value varies with the platform on which the JVM is running. 

    -XX:InlineSmallCode= 

     

    当编译的代码小于指定的值时,内联编译的代码 

    -XX:MaxInlineSize=35 

     

    内联方法的最大字节数 

    -XX:FreqInlineSize= 

     

    内联频繁执行的方法的最大字节码大小 

    -XX:LoopUnrollLimit= 

     

    Unroll loop bodies with server compiler intermediate representation node count less than this value. The limit used by the server compiler is a function of this value, not the actual value.

    The default value varies with the platform on which the JVM is running. 

    -XX:InitialTenuringThreshold=7 

     

    设置初始的对象在新生代中最大存活次数 

    -XX:MaxTenuringThreshold= 

     

    设置对象在新生代中最大的存活次数,最大值15,并行回收机制默认为15,CMS默认为4 

     
  • 相关阅读:
    C#中的正则表达式(1)
    sql link
    Repeater控件绑定数据、分页、数据操作,最佳代码
    存储过程事物
    sql db link string
    存储过程返回值
    net打包
    excel c# 输出
    常用的js验证数字,电话号码,传真,邮箱,手机号码,邮编,日期
    sql 大全
  • 原文地址:https://www.cnblogs.com/erichi101/p/13500444.html
Copyright © 2011-2022 走看看