学习 尚硅谷 宋红康 JVM从入门到精通 的学习笔记

生产环境中的问题

生产环境发生了内存溢出该如何处理
生产环境应该给服务器分配多少内存合适?
如何对垃圾回收器的性能进行调优?
生产环境CPU负载飙高该如何处理?
生产环境应该给应用分配多少线程合适?
不加log,如何确定请求是否执行了某一行代码?
不加log,如何实时查看某个方法的入参与返回值?

为什么要调优

1.防止出现OOM:一出现oom程序就宕机了,所以要防止出现oom
2.解决OOM:出现oom要解决oom
3.减少Full GC出现的频率:Full GC不可能不出现,要尽量减少Full GC频率,因为Full GC会出现stop the world 情况.暂停时间过长的话,会影响用户的体验

不同阶段的考虑

1.上线前 : 比如说cpu使用率过高,请求延迟,tps降低等等,内存溢出 内存泄露
2.项目运行阶段:希望平稳运行,需要生产环境的监控,需要查看gc日志等等
3.线上出现OOM:必须要进行处理了.

监控的依据

  1. 运行日志
  2. 异常堆栈
  3. GC日志
  4. 线程快照
  5. 堆转储快照(dump文件)

调优的大方向

  1. 合理地编写代码
  2. 充分并合理的使用硬件资源
  3. 合理地进行JVM调优

    jvm只是其中的一个考虑点而已,如果你程序写的跟一坨屎一样,你jvm调优再好也没用.

    性能优化的步骤

第1步 性能监控 (发现问题)

性能监控是一种以非强行或者入侵方式 收集或查看 应用运营性能数据的活动.
监控通常是指一种在生产、质量评估或者开发环境下实施的带有预防或者主动性的活动。
当应用相关干系人提出性能问题却没有提供足够多的线索时,首先我们需要进行性能监控,最后是性能分析。

性能监控发现的问题等等:
GC频繁
cpu load过高
OOM
内存泄露
死锁
程序响应时间较长

第2步 性能分析 (排查问题)

性能分析是一种以侵入方式主动的收集运行性能数据的活动,它会影响应用的吞吐量或者响应时间。
性能分析是针对性能问题的答复结果,关注的范围通常比性能监控更加集中。
性能分析会影响程序的吞吐量或者响应时间,所以很少在生产环境下进行,通常是在质量评估、系统测试或者开发环境下进行,是性能监控之后的步骤。

性能分析手段:
打印GC日志,通过GCviewer或者 http://gceasy.io来分析异常信息
灵活运用 命令行工具、jstack、jmap、jinfo等
dump出堆文件,使用内存分析工具分析文件
使用阿里Arthas、jconsole、JVisualVM来实时查看JVM状态
jstack查看堆栈信息

第3步 性能调优 (解决问题)

性能调优是一种为了改善应用响应性或者吞吐量而更改参数、源代码、属性配置的行为,性能调优是在性能监控、性能分析之后的活动。

目的是希望减少gc的频率,full gc的参数,或者是以较小的占用获得程序较高的响应性或者吞吐量。

适当增加内存,根据业务背景选择垃圾回收器
优化代码,控制内存使用
增加机器,分散节点压力
合理设置线程池线程数量
使用中间件提高程序效率,比如缓存、消息队列等
其他……

性能评价/测试指标

jvm调优的时候需要重点关注 停顿时间和吞吐量这两个指标

1-停顿时间(或响应时间)

image.png
image.png

2-吞吐量

对单位时间内完成的工作量(请求)的量度
在GC中:运行用户代码的时间占总运行时间的比例
(总运行时间:程序的运行时间+内存回收的时间) 吞吐量为1-1/(1+n),其中-XX::GCTimeRatio=n

3-并发数
同一时刻,对服务器有实际交互的请求数
假如说系统有1000个人同时在线,那么估计并发数在5%~15%之间,也就是同时的并发量: 50~150之间.

4-内存占用
Java堆区所占的内存大小

5-相互间的关系

以高速公路通行状况为例

吞吐量可以理解为每天通过高速公路收费站的车辆的数据(也可以理解为收费站收取的高速费)
并发数可以理解为高速公路上正在行驶的车辆的数目
响应时间可以理解为车速

并发数比较小的时候响应时间就比较快了,吞吐量就也不算太高.随着并发数越来越多,这个时候响应时间就会降下来,但是整体的吞吐量有明显的提升.
并发数越来越多,此时响应时间就会越来越慢,吞吐量反而会降低
如果此时再出现点问题,那么程序就堵死了,响应时间可能就为0了,那么吞吐量就为0了.