调优基本概念

在调整JVM性能时,通常有三个组件需要考虑:

  1. 堆大小调整
  2. 垃圾收集器调整
  3. JIT编译器

大多数调优选项都与调整堆大小和选择合适的垃圾收集器有关,JIT编译器对性能也有很大影响,但很少需要对其进行调优,尤其是针对较新版本的JVM。

通常,在进行Java程序调优的时候,会重点关注两个主要指标:

  • 响应性:应用程序对请求进行响应的速度,对于专注响应性的应用程序,长时间的暂停是不可接受的,需要在最短时间内做出响应
  • 吞吐量:侧重于在特定时间内最大化应用程序的工作量,对于专注于吞吐量的应用程序,符合要求的暂停是可以接受的。

JVM本身是在不断优化的,系统瓶颈的核心还是在于应用代码,更多的情况下还是要专注于应用代码的优化。

常用JVM参数

参数 描述
-XX:+AlwaysPreTouch JVM启动时分配内存,堆的每个页面都在初始化期间按需置零,而不是在应用程序执行期间递增
-XX:Errorfile = filename 错误日志
-XX:+TraceClassLoading 跟踪类加载信息
-XX:+PrintClassHistogram 按下Ctrl+Break后打印类信息
-Xmx -Xms 最大堆 最小堆
-xx:permSize 永久代大小
-xx:metaspaceSize 元数据空间大小
-XX:+HeapDumpOnOutOfMemoryError 当抛出OOM时进行HeapDump
-XX:+HeapDumpPath OOM时堆导出的路径
-XX:OnOutOfMemoryError 当发生OOM时执行用户指定的命令

命令: java -XX:+PrintFlagsFinal -version 会 打印所有的-XX参数及其默认值

GC调优思路

  1. 分析场景,如:启动速度慢,偶尔出现响应慢于平均水平或出现卡顿
  2. 确定目标,如:内存占用,低延时,吞吐量
  3. 收集日志,如:通过参数配置收集GC日志,通过JDK工具查看GC状态
  4. 分析日志,如:使用工具辅助分析日志,查看GC次数,GC时间
  5. 调整参数,如:切换垃圾收集器或者调整垃圾收集器参数

常用GC参数

参数 描述
-XX:ParallelGCThreads 并行GC线程数量
-XX:ConcGcThreads 并发GC线程数量
-XX:MaxGCPauseMillis 最大停顿时间,单位毫秒,GC尽力保证回收时间不超过设定值
-XX:GCTimeRatio 垃圾收集时间占总时间的比值,取值0-100,默认99,即最大允许1%的时间做GC
-XX:SurvivorRatio 设置eden区大小和survivor区大小的比例,8表示两个survivor:eden=2:8,即一个survivor占年轻代的1/10
-XX:NewRatio 新生代和老年代的比,4表示新生代:老年代=1:4,即年轻代占堆的1/5
-verbose:gc,-XX:+PrintGC 打印GC的简要信息
-XX:+PrintGCDetails 打印GC详细信息(JDK9之后不再使用)
-XX:+PrintGCTimeStamps 打印GC发生的时间戳(JDK9之后不再使用)
-Xloggc:log/gc.log 指定GC log的位置,以文件输出
-XX:PrintHeapAtGC 每次GC后都打印堆信息

垃圾收集器Parallel参数调优

Parallel垃圾收集器在JDK8中是JVM默认的垃圾收集器,它是以吞吐量优先的垃圾收集器。其可调节的参数如下:

参数 描述
-XX:+UseParallelGC 新生代使用并行垃圾收集器
-XX:+UseParallelOldGC 老年代使用并行垃圾收集器
-XX:ParallelGCThreads 设置用于垃圾回收的线程数
-XX:+UseAdaptiveSizePolicy 打开自适应GC策略

垃圾收集器CMS参数调优

CMS垃圾收集器是一个响应时间优先的垃圾收集器,Parallel收集器无法满足应用程序延迟要求时再考虑使用CMS垃圾收集器,从JDK9开始CMS收集器已不建议使用,默认用的是G1垃圾收集器。

参数 描述
-XX:+UseConcMarkSweepGC 新生代使用并行收集器,老年代使用CMS+串行收集器
-XX:+UseParNewGC 新生代使用并行收集器,老年代CMS收集器默认开启
-XX:CMSInitiatingOccupanyFraction 设置触发GC的阈值,默认68%,如果内存预留空间不够,就会引起concurrent mode failure
-XX:+UseCMSCompactAtFullCollection Full GC后,进行一次整理,整理过程是独占的,会引起停顿时间变长
-XX:+CMSFullGCsBeforeCompaction 设置进行几次Full GC后进行一次碎片整理
-XX:+CMSClassUnloadingEnabled 允许对类元数据进行回收
-XX:+UseCMSInitiatingOccupanyOnly 表示只在达到阈值的时候才进行CMS回收
-XX:+CMSIncrementalMode 使用增量模式,比较适合单CPU

垃圾收集器G1参数调优

G1收集器是一个兼顾吞吐量和响应时间的收集器,如果是大堆(如堆的大小超过6GB),堆的使用率超过50%,GC延迟要求稳定且可预测的低于0.5秒,建议使用G1收集器。

参数 描述
-XX:G1HeapRegionSize 设置Region大小,默认heap/2000
-XX:G1MixedGCLiveThresholdPercent 老年代依靠Mixed GC, 触发阈值
-XX:G1OldSetRegionThresholdPercent 定多包含在一次Mixed GC中的Region比例
-XX:+ClassUnloadingWithConcurrentMark G1增加默认开启,在并发标记阶段结束后,JVM即进行类型卸载
-XX:G1NewSizePercent 新生代的最小比例
-XX:G1MaxNewSizePercent 新生代的最大比列
-XX:G1MixedGCCountTraget Mixed GC数量控制

调优示例

示例代码:

@SpringBootApplication
public class SpringBootDemoApplication { public static void main(String[] args) {
SpringApplication.run(SpringBootDemoApplication.class, args);
Executors.newScheduledThreadPool(1)
.scheduleAtFixedRate(
() -> {
new Thread(
() -> {
for (int i = 0; i < 150; i++) {
try {
byte[] temp = new byte[1024 * 512];
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
})
.start();
},
100,
100,
TimeUnit.MILLISECONDS);
}
}

GC分析主要查看GC导致的Stop The World的时间,它会导致程序的延时增加。

示例代码运行的时候建议指定其堆内存的最大值,启动时添加JVM参数-Xmx1024m。程序运行起来之后可以利用jps或者jcmd产看运行的程序进程号。

拿到进程号之后利用jstat命令查看GC信息,如动态监控GC统计信息,间隔1000毫秒统计一次,每10行数据后输出列标题:

上述两个步骤也可以合并成一个 jstat -gc -h10 $(jcmd | grep “com.example.springbootdemo.SpringBootDemoApplication” | awk ‘{print $1}’) 1000

当然除了动态监控GC信息,也可以将GC日志信息打印到文件,然后利用GC分析工具进行分析。
在程序启动时添加JVM参数”-Xmx1024m -Xloggc:/gc.log“,则可以可以将GC日志打印到gc.log文件,然后可以利用GCViewer工具辅助分析GC日志文件,参考地址:https://github.com/chewiebug/GCViewer

GCViewer下载后双击gcviewer-x.xx-SNAPSHOT.jar文件即可运行,然后将gc.log日志文件导入即可观察GC信息。

GC调优之前,我们需要了解当前JVM参数的信息。命令 java -XX:+PrintFlagsFinal -version 会打印所有的JVM参数,如需查看指定参数,如查看UseAdaptiveSizePolicy的值可以使用 java -XX:+PrintFlagsFinal -version | grep UseAdaptiveSizePolicy

调整-XX:ParallelGCThreads的值可以指定GC并发的线程数,如在JVM启动参数中可以添加 “-Xmx1024m -XX:ParallelGCThreads=4”,调节GC并发的线程数,观察GC的信息,如Full GC次数FGC,Full GC的总时间FGCT,GC的总时间GCT等进行调优。

同样我们可以在JVM启动参数中指定-XX:MaxGCPauseMills,使用G1收集器-XX:+UseG1GC等,调节JVM启动参数,收集GC日志,更具监控进行相应的调节,进而找到最优值。

JVM参数及调优的更多相关文章

  1. [JVM教程与调优] 什么是JVM运行时参数?

    我们接着上一章节[JVM教程与调优] JVM都有哪些参数类型?的内容继续讲解,这章我们来介绍一下:如何查看JVM运行时参数.这一点十分重要,因为我们在进行JVM参数调优的时候,我们首先得知道目前系统运 ...

  2. Java系列笔记(4) - JVM监控与调优

    目录 参数设置收集器搭配启动内存分配监控工具和方法调优方法调优实例     光说不练假把式,学习Java GC机制的目的是为了实用,也就是为了在JVM出现问题时分析原因并解决之.通过学习,我觉得JVM ...

  3. JVM监控与调优

    目录 参数设置收集器搭配启动内存分配监控工具和方法调优方法调优实例     转:http://www.cnblogs.com/zhguang/p/java-jvm-gc.html光说不练假把式,学习J ...

  4. [java] JVM监控与调优

    原文出处:http://www.cnblogs.com/zhguang/p/java-jvm-gc.html   光说不练假把式,学习Java GC机制的目的是为了实用,也就是为了在JVM出现问题时分 ...

  5. Tomcat性能调优-JVM监控与调优

    参数设置 在Java虚拟机的参数中,有3种表示方法用"ps -ef |grep "java"命令,可以得到当前Java进程的所有启动参数和配置参数: 标准参数(-),所有 ...

  6. spark submit参数及调优

    park submit参数介绍 你可以通过spark-submit --help或者spark-shell --help来查看这些参数.   使用格式:  ./bin/spark-submit \   ...

  7. JVM监控和调优常用命令工具总结

    JVM监控和调优 在Java应用和服务出现莫名的卡顿.CPU飙升等问题时总是要分析一下对应进程的JVM状态以定位问题和解决问题并作出相应的优化,在这过程中Java自带的一些状态监控命令和图形化工具就非 ...

  8. spark submit参数及调优(转载)

    spark submit参数介绍 你可以通过spark-submit --help或者spark-shell --help来查看这些参数. 使用格式:  ./bin/spark-submit \ -- ...

  9. Java启动参数及调优

    java启动参数共分为三类: 其一是标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容:其二是非标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且 ...

随机推荐

  1. 夯实Java基础系列14:深入理解Java枚举类

    目录 初探枚举类 枚举类-语法 枚举类的具体使用 使用枚举类的注意事项 枚举类的实现原理 枚举类实战 实战一无参 实战二有一参 实战三有两参 枚举类总结 枚举 API 总结 参考文章 微信公众号 Ja ...

  2. touch,stat

    touch(选项)(参数) 一是可以用来创建空文件,二是用来改变文件的元属性-a:修改文件的访问时间为当前时间-m:修改文件的改变时间为当前时间-r:把文件的属性修改成和某些文件一样的时间-t:修改成 ...

  3. spring-boot-plus XSS跨站脚本攻击处理

    XSS跨站脚本攻击处理 XSS:Cross Site Scripting 跨站脚本攻击(XSS),是目前最普遍的Web应用安全漏洞.这类漏洞能够使得攻击者嵌入恶意脚本代码到正常用户会访问到的页面中,当 ...

  4. KafkaStream低级别API

    开发者可以通过Processor接口来实现自己的自定义处理逻辑.接口提供了Process和Punctuate方法. 其中:Process方法用于处理接受到的消息 Punctuate方法指定时间间隔周期 ...

  5. 关于人工智能和python

    人工智能的话题在近几年可谓是相当火热,前几天看快本时其中有一个环节就是关于人工智能的,智能家电.智能机器人.智能工具等等,在我的印象里,提到人工智能就会出现 Python,然后我便在网上查找了相关信息 ...

  6. The Largest Clique UVA - 11324

    题文:https://vjudge.net/problem/UVA-11324 题解: 这个题目首先可以发现,只要是一个强连通分量,要么都选,要么都不选,将点权看成强连通分量的点数,所以这个题目就转化 ...

  7. Vue-CLI 项目在pycharm中配置

    Vue-CLI Vue-CLI 项目在pycharm中配置 第一步 pycharm索引到vue项目的根目录,打开 第二步 安装vue.js插件来高亮 .vue 文件代码(见插图) 第三步 第四步 配置 ...

  8. Jmeter结构体系及运行顺序

    一:jmeter运行原理: jmeter时以线程的方式来运行的(由于jmeter是java开发的所以是运行在JVM虚拟机上的,java也是支持多线程的) 二:jmeter结构体系 1.取样器smapl ...

  9. XSS中的同源策略和跨域问题

    转自 https://www.cnblogs.com/chaoyuehedy/p/5556557.html 1 同源策略 所谓同源策略,指的是浏览器对不同源的脚本或者文本的访问方式进行的限制.比如源a ...

  10. shark恒破解笔记6-摆脱NAG

    1.打开软件后,发现是未注册,然后点击关闭按钮,会弹出窗口 我们的目的就是为了能够去掉这个弹窗. 2.对这个程序进行查壳,没有什么发现 3.载入OD里面,F9运行起来,随后切换到程序主界面点击关闭按钮 ...