JVM 参数怎么调

作者: 老瓦在霸都 | 来源:发表于2020-05-31 20:02 被阅读0次

    基于 JVM 的语言和应用程序汗牛充栋,不仅限于 Java , 还有 Scala , JPython, JRuby。对于 JVM 的调优是每个JVM 应用开发者必需要了解的。

    先回顾一下 JVM 的结构

    JVM 结构

    JVM structure

    堆内部的分代

    • 年轻代 Young Generation: 一般分为伊甸园 Eden 和幸存区 Survivor(通过分为两个区S0, S1), 新创建的对象放在Eden 区
    • 年老代 Old Generation
    • 永久代 Permanent Generation, Java 8 中改为 MetaSpace
    JVM Heap

    JVM 参数调优

    JVM 参数既多且杂,如何提纲挈领,避免挂一漏万呢?个人的想法是掌握原理,了解常用的参数就好了,以度量来驱动适用于你的应用程序的参数设置。

    • 1)设计:
      分析你的应用程序要求的吞吐量如何,它对于短暂的停顿是否敏感,从而了解到大约需要多大的内存,从而设置一个比较合理的参数,例如
        -Xms2048m
        -Xmx2048m
        -XX:MetaspaceSize=128m
        -XX:MaxMetaspaceSize=256m
        -XX:CompressedClassSpaceSize=256m
        -Xss1m
    
    • 2) 运行
      在程序运行期间设置如下参数来打印 GC 的运行时信息
    -XX:+PrintGCDetails 
    -XX:+PrintGCDateStamps 
    -XX:+PrintHeapAtGC 
    -XX:+PrintTenuringDistribution 
    -XX:+PrintGCApplicationStoppedTime 
    -XX:+PrintPromotionFailure 
    -XX:+UseGCLogFileRotation 
    -XX:NumberOfGCLogFiles=10 
    -XX:GCLogFileSize=10M 
    -Xloggc:./bin/../logs/gc.log
    -XX:OnOutOfMemoryError="sh ./bin/oom-hander.sh"
    
    • 3) 监控
      重点监控如下指标

      • heap 堆内存使用情况
      • non-heap 非堆内存使用情况
      • gc pause 垃圾回收信息
      • oom 内存溢出错误
      • stackOverFlow 栈溢出错
    • 4)调优
      调整参数,以期更合理的内存分配和垃圾回收

    常用JVM 调优参数

    • JVM内存与垃圾收集
      • GC分类:
        • Minor GC
          • 也称 Scavenge GC, 收集新生代
          • 新对象在 Eden区申请空间失败时会触发
        • Major GC
          • 也称 Full GC, 收集新生代,年老代和永久代
          • 年老代或永久代被写满时会触发
      • GC算法:
        • 引用计数 Reference Counting
        • 标记清除 Mark-Sweep
        • 复制 Copying
        • 标记-压缩 Mark-Compact
      • JVM参数:
        • -Xmx=2048m 堆的最大值
        • -Xms=1024m 堆的初始值
        • -Xmn=128m 年轻代大小的值
        • -XX:newSize= 年轻代大小的初始值
        • -XX:maxNewSize= 年轻代大小的最大值
        • -XX:NewRatio= 年轻代与年老代的比例=年老代大小/年轻代大小
        • -XX:SurvivorRatio= 年轻代中的 Eden 区与 Survivor 区的比例=Eden区大小/(S1或S2区的大小)
        • -XX:MetaSpaceSize= 元空间(永久代)大小的初始值
        • -XX:MaxMetaSpaceSize= 元空间(永久代)大小的最大值
        • -Xss: 每个线程的堆栈大小
        • -XX:MaxDirectMemorySize= 直接内存大小的最大值
        • -XX:CompressedClassSpaceSize= 堆在小于32G时会将类信息放入 CompressedClassSpace, 即地址将64bit压缩成32bit
        • -XX:+AlwaysPreTouch 启动时预先初始化内存页,这样运行期就省去了初始化内存页这个步骤了
      • 指标
        • Throughput 吞吐量
          • the percentage of total time not spent in GC considered over long periods of time
        • Pauses 暂时时间
          • the times when an application appears unresponsive because GC is occurring
      • 分代 Generations 及适应的参数和回收算法
        • 永久代(元数据空间) MetaSpace
          • -XX:MetaspaceSize=128m
            • the initial amount of space(the initial high-water-mark)
          • -XX:MaxMetaspaceSize=256m
            • the maximum amount of space to be allocated for class metadata
          • -XX:MinMetaspaceFreeRatio=
            • min high-water-mark
          • -XX:MaxMetaspaceFreeRatio=
            • max high-water-mark
        • 年轻代 Young Generation
          • Serial
            • -XX:+UseSerialGC
          • ParNew
            • -XX:+UseParNew
          • Parallel Scavenge
            • -XX:+UseParallelGC
            • -XX:ParallelGCThreads=
        • 年老代 Old Generation
          • Serial Old
          • Parallel Old
          • CMS(Concurrent Mark Sweep)
            • -XX:+UseConcMarkSweepGC
          • G1(Gargage First)
            • -XX:+UseG1GC
            • -XX:MaxGCPaouseMillis=
            • -XX:ParallelGChreads=
      • Behavior-BasedTuning
        • 暂停时间目标 Pause Time Goal
          • -XX:MaxGCPauseMillis=
        • 吞吐量目标Throughput Goal
          • -XX:GCTimeRatio=
            • -XX:GCTimeRatio=19 sets a goal of 1/20th or 5% of the total time for GC
        • 体积目标 Footprint Goal
          • reduces the size of the heap until one of the goals(invariably the throughput goal) cannot be met
      • 调优策略 Tuning Strategy
        • 选择适合你的应用程序的吞吐量目标.
        • 选择适合的暂停时间目标,这点要和上面的吞吐量目标可能有冲突,要根据你的需要做出平衡

    实例

    以 Cassandra 为例,它是的一个高性能的分布式NOSQL 数据存储系统,它设置了如下 JVM 参数:

    bin/java -Xloggc:./bin/../logs/gc.log 
    -ea 
    -XX:+UseThreadPriorities 
    -XX:ThreadPriorityPolicy=42 
    -XX:+HeapDumpOnOutOfMemoryError 
    -Xss256k 
    -XX:StringTableSize=1000003 
    -XX:+AlwaysPreTouch 
    -XX:-UseBiasedLocking 
    -XX:+UseTLAB 
    -XX:+ResizeTLAB 
    -XX:+UseNUMA 
    -XX:+PerfDisableSharedMem 
    -Djava.net.preferIPv4Stack=true 
    -XX:+UseParNewGC 
    -XX:+UseConcMarkSweepGC 
    -XX:+CMSParallelRemarkEnabled 
    -XX:SurvivorRatio=8 
    -XX:MaxTenuringThreshold=1 
    -XX:CMSInitiatingOccupancyFraction=75 
    -XX:+UseCMSInitiatingOccupancyOnly 
    -XX:CMSWaitDuration=10000 
    -XX:+CMSParallelInitialMarkEnabled 
    -XX:+CMSEdenChunksRecordAlways 
    -XX:+CMSClassUnloadingEnabled 
    -XX:+PrintGCDetails 
    -XX:+PrintGCDateStamps 
    -XX:+PrintHeapAtGC 
    -XX:+PrintTenuringDistribution 
    -XX:+PrintGCApplicationStoppedTime 
    -XX:+PrintPromotionFailure -XX:+UseGCLogFileRotation 
    -XX:NumberOfGCLogFiles=10 
    -XX:GCLogFileSize=10M 
    -Xms4096M 
    -Xmx4096M 
    -Xmn800M 
    -XX:+UseCondCardMark 
    -XX:CompileCommandFile=./bin/../conf/hotspot_compiler 
    -javaagent:./bin/../lib/jamm-0.3.0.jar 
    -Dcassandra.jmx.local.port=7199 
    -Dcom.sun.management.jmxremote.authenticate=false 
    -Dcom.sun.management.jmxremote.password.file=/etc/cassandra/jmxremote.password 
    -Djava.library.path=./bin/../lib/sigar-bin 
    -XX:OnOutOfMemoryError=kill -9 %p 
    -Dlogback.configurationFile=logback.xml 
    -Dcassandra.logdir=./bin/../logs 
    -Dcassandra.storagedir=./bin/../data 
    -Dcassandra-foreground=yes 
    -cp ./bin/../conf:./bin/../build/classes/main:./bin/../build/classes/thrift:...jar: org.apache.cassandra.service.CassandraDaemon
    

    监控与观察

    一般来说,比较常用的方法是通过 JMX 和 GC log 来度量你的 JVM 参数设置是是否合理,一旦发现异常或者 OOM 要马上采取措施进行调整

    jstat -gcutil 1324
      S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
      0.00   0.00  15.10   7.84  97.24  92.57      2       0.017     1      0.034    0.051
    
    • S0: Survivor space 0 生存空间0利用率占该空间当前容量的百分比
    • S1: Survivor space 1 幸存者空间1利用率占该空间当前容量的百分比
    • E: Eden space 伊甸园空间利用率占空间当前容量的百分比
    • O: Old space 旧空间利用率占空间当前容量的百分比
    • M: Metaspace 元空间利用率占空间当前容量的百分比
    • CCS: Compressed class space 压缩的类空间利用率(以百分比表示)
    • YGC: Young generation GC 年轻代GC次数.
    • YGCT: Young generation GC Time年轻代GC耗时
    • FGC: Full GC 完全GC次数
    • FGCT: Full GC Time 完全GC耗时
    • GCT: Total GC Time 总GC耗时

    关于 JVM 内存溢出的分析可以参考以前写的 内存溢出不可怕,手足无措才尴尬

    参考资料

    相关文章

      网友评论

        本文标题:JVM 参数怎么调

        本文链接:https://www.haomeiwen.com/subject/ouflzhtx.html