JVM 总结(三)

1. 调优前规划

1.1 考虑原则

调优前要熟悉业务场景,选择合适的垃圾回收器,若业务需要优先响应时间,则应选择STW时间短的,可选择CMS、G1、ZGC;若业务需要吞吐量优先,则可以选用PS+PO。
响应时间,STW越短,响应时间越好,如网站、GUI、API等,需要优先考虑响应时间。
吞吐量,指的是用户代码/(用户代码+GC时间),如数据挖掘、科学计数法等,需要优先考虑吞吐时间。
一般情况下,我们会选择满足某一响应时间的前提下,达到xxx的吞吐量。

1.2 规划硬件需求

根据业务计算内存需求,并选定合适的CPU,在满足条件的情况下,选定更高的CPU。

1.3 规划分代情况

根据业务推导,设定年代的大小,以及升级的年龄,年龄最大为15。

1.4 设定日志参数

1.4.1 日志参数的设置

一般log文件的存储有两种形式,第一种是循环利用logfile,设定logfile的大小、个数等,循环产生日志。第二种是,每天产生一个logfile。
循环利用logfile的参数设置:

-Xloggc:/outputfile/xxxx/ssss-gc-%t.log
-XX:+UseGCLogFileRotation
-XX:NumberOfCGLogFiles = num
-XX:GCLogFileSize = num
-XX:PrintGCDetails	#打印GC详细信息
-XX:PrintGCDataStamps	#打印GC执行时间
-XX:PrintGCCause

1.4.2 GC日志查看

不同的垃圾回收器,日志格式也是不相同的。
PS为例:

【GC : yong GC / FULLGC】   
【(GC reason  : Allocation Failure)】  
【DefNew(新生代) : before GC size -> after GC size
【total NewGenerationSize】cost-time】  
【before GC heap size -> after GC size
【total heap size】total-cost-time 】

2. 问题检测

在很多情况下,调优需要先定位问题,然后才能选择合适的调优方案。类似于内存飙升、内存居高不下、out of memory(内存溢出)、memory leak(内存泄漏)等,需要先定位问题原因。

  1. jps 查找当前执行的java进程
  2. top 找出当前那个进程的cpu高
  3. top -Hp 对应进程中哪个线程cpu高
  4. jstack 定位线程状况,线程的状态有waiting(无限期等待另一个线程执行特定操作)、timed_wating(有时限的等待另一个线程的特定操作)、blocked(受阻塞并等待监视器锁)、runnable(在虚拟机内执行的)、terminated(已退出的)
  5. jinfo [option] <pid>,查看JVM参数和动态修改部分JVM参数的命令
  6. jstat,查看JVM运行时的状态信息,包括内存状态、垃圾回收等。
  7. jconsolejvisualVM,图形化节点监测JVM运行情况,jvisualVM界面更直观点,在测试环境使用,线上环境不适合,因为需要开启JMX远程连接,占用工作线程运行空间。
  8. jmap,查看堆内存使用情况,一般结合jhat使用。
  • jmap -histo:live 7392 查找有多少存活的对象,去掉:live是查找有多少对象产生,可以配合管道使用,例如:jmap -histo 7392
  • jmap -dump:format=b,file=xxx pid 导出堆内存,但是,在线上系统导出堆内存的话,会对进程产生很大的影响,甚至造成卡顿,内存特别大的话,最好不要执行此操作。可以选择使用阿里的在线排查工具,arthas。关于arthas以后再做笔记。

3. 常用参数

3.1 G1常用参数

  • -XX:+UseG1GC
  • -XX:MaxGCPauseMillis 建议值,G1会尝试调整Young区的块数来达到这个值
  • -XX:GCPauseIntervalMillis ?GC的间隔时间
  • -XX:+G1HeapRegionSize 分区大小,建议逐渐增大该值,1 2 4 8 16 32。 随着size增加,垃圾的存活时间更长,GC间隔更长,但每次GC的时间也会更长 ZGC做了改进(动态区块大小)
  • G1NewSizePercent 新生代最小比例,默认为5%
  • G1MaxNewSizePercent 新生代最大比例,默认为60%
  • GCTimeRatio GC时间建议比例,G1会根据这个值调整堆空间
  • ConcGCThreads 线程数量
  • InitiatingHeapOccupancyPercent 启动G1的堆空间占用比例

3.2 CMS 常用参数

  • -XX:+UseConcMarkSweepGC
  • -XX:ParallelCMSThreads CMS线程数量
  • -XX:CMSInitiatingOccupancyFraction 使用多少比例的老年代后开始CMS收集,默认是68%(近似值),如果频繁发生SerialOld卡顿,应该调小,(频繁CMS回收)
  • -XX:+UseCMSCompactAtFullCollection 在FGC时进行压缩
  • -XX:CMSFullGCsBeforeCompaction 多少次FGC之后进行压缩
  • -XX:+CMSClassUnloadingEnabled
  • -XX:CMSInitiatingPermOccupancyFraction 达到什么比例时进行Perm回收
  • GCTimeRatio 设置GC时间占用程序运行时间的百分比
  • -XX:MaxGCPauseMillis 停顿时间,是一个建议时间,GC会尝试用各种手段达到这个时间,比如减小年轻代

3.3 Parallel常用参数

  • -XX:SurvivorRatio
  • -XX:PreTenureSizeThreshold 大对象到底多大
  • -XX:MaxTenuringThreshold
  • -XX:+ParallelGCThreads 并行收集器的线程数,同样适用于CMS,一般设为和CPU核数相同
  • -XX:+UseAdaptiveSizePolicy 自动选择各区大小比例

3.4 GC常用参数

  • -Xmn -Xms -Xmx -Xss 年轻代 最小堆 最大堆 栈空间
  • -XX:+UseTLAB 使用TLAB,默认打开
  • -XX:+PrintTLAB 打印TLAB的使用情况
  • -XX:TLABSize 设置TLAB大小
  • -XX:+DisableExplictGC System.gc()不管用 ,System.gc()会触发FGC
  • -XX:+PrintGC 打印GC日志
  • -XX:+PrintGCDetails 打印GC日志详细信息
  • -XX:+PrintHeapAtGC
  • -XX:+PrintGCTimeStamps
  • -XX:+PrintGCApplicationConcurrentTime (不常用) 打印应用程序时间
  • -XX:+PrintGCApplicationStoppedTime (不常用) 打印暂停时长
  • -XX:+PrintReferenceGC (不常用) 记录回收了多少种不同引用类型的引用
  • -verbose:class 类加载详细过程
  • -XX:+PrintVMOptions
  • -XX:+PrintFlagsFinal 最终参数值
  • -XX:+PrintFlagsInitial 默认参数值
  • -Xloggc:opt/log/gc.log
  • -XX:MaxTenuringThreshold 升代年龄,最大值15
  • -XX:+PrintCommandLineFlags -version 观察虚拟机配置
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值