6-JVM经常使用工具和优化

JVM 经常使用工具和优化

JDK 自带的

jconsole

jvisualvm

三方的工具

arthas

调优关注点(内存、GC):

内存redis

  • MAT
  • XElephant
  • 在线:perfma

GC数据库

拿到GC日志,分析GC日志(吞吐量,停顿时间,垃圾回收次数;这三个是评判垃圾收集器好坏的标准)后端

  • 本地:GCViewer
  • 在线:gceasy.io

在什么状况下调优

体现系统性能的参考因素

首先咱们须要知道系统当前的运行情况,也就是系统的性能好坏,才能判断是否须要调优。若是系统的响应时间很短,计算机的资源使用也很低,那咱们作系统调优就彻底是为了调优而调优。那么衡量系统性能的指标到底有哪些呢?性能优化

  • 响应时间:响应时间是衡量系统性能的重要指标之一,响应时间越短,性能越好,通常一个接口的响应时间是在毫秒级。响应时间还包括数据库响应时间、服务端响应时间、网络响应时间、客户端响应时间。
  • TPS:指系统接口的 TPS(每秒事务处理量),由于 TPS 体现了接口的性能,TPS 越大,性能越好。在系统中,吞吐量分为两种:磁盘吞吐量和网络吞吐量。
  • 计算机资源分配使用率:一般由 CPU 占用率、内存使用率、磁盘 I/O、网络 I/O 来表示资源使用率。这几个参数比如一个木桶,若是其中任何一块木板出现短板,任何一项分配不合理,对整个系统性能的影响都是毁灭性的。

JVM 调优都作些什么?

具体来讲 JVM 调优须要包括两方面:合理地设置 JVM 的内存空间和选择合适的垃圾回收器。网络

  • 内存空间的分配设置:JVM 内存分配不合理带来的性能表现并不会像内存溢出问题这么突出,最直接的表现就是频繁的 GC,这会致使上下文切换等性能问题,从而下降系统的吞吐量、增长系统的响应时间。具体的实现包括调整堆内存空间减小 Full GC、调全年轻代减小 MinorGC、设置合理的 Eden 和 Survivor 区的比例。
  • 选择合适的垃圾回收器:垃圾回收主要是指堆和方法区的回收,堆中的回收主要是对象的回收,方法区的回收主要是废弃常量和无用的类的回收。垃圾收集器的种类不少,不一样的场景有不一样的选择。对于每次操做的响应时间要求比较高的,咱们能够选择响应速度较快的 GC回收器,好比 CMS 回收器和 G1 回收器;而对系统吞吐量有较高要求时,就能够选择 Parallel Scavenge 回收器来提升系统的吞吐量。

是否须要 JVM 调优?

通常项目确定是不须要进行 JVM 调优的,由于 JVM 自己就是为这种低延时、高并发、大吞吐的服务设计和优化的,咱们不多须要去改变什么。因此,咱们每每更偏重于应用服务自己的调优。 并发

在一些应用中,好比大数据计算引擎,是一种很是极端的 JVM 应用,对延时的要求并不高,但对吞吐量要求很高,会有大量的短生命周期对象产生,同时也有大量的对象生存时间很是久,咱们就须要对特定的一些 JVM 参数进行修改。 app

再好比生产环境中出现内存溢出,咱们须要判断是因为大峰值下没有限流,瞬间建立大量对象而致使的内存溢出,仍是是因为内存泄漏而致使的内存溢出。对于内存泄漏致使的,这种问题就是程序的 Bug,咱们须要及时找到问题代码进行修改,而不是调整 JVM。 负载均衡

JVM 在很大程度上减轻了 Java 开发人员投入到对象生命周期管理的精力。在使用对象的时候,JVM 会自动分配内存给对象,在不使用的时候,垃圾回收器会自动回收对象,释放占用的内存。因此通常状况下咱们是不须要调优的。固然事无绝对,某些特殊场景就须要咱们进行参数调整,但调整的前提必定是你对 JVM 的运行原理很是熟悉才行。异步

JVM错误排查与解决案例

JVM性能优化到底从发现到解决的历程:发现问题-排查问题-解决问题分布式

案列一:

发现问题:JVM日志 gc.log 文件,经过JVM工具(好比:gceasy)查看并发现问题;好比GC的次数过多;能够经过工具查看到GC次数【新生代和老年代分别的GC次数】。GC频繁:如何判断GC频繁呢?有个参照【好比服务刚上线GC5次,运行一段时间后10次,在以后30次,在以后50次,依次类推】

排查问题:打印出JVM GC日志,查看minorGC(新生代GC)或者majorGC(老年代GC)

解决问题:适当增长堆内存空间,或者选择合适的垃圾收集器

案例二:

发现问题:OOM

排查问题:在JVM参数中配置,若是发生了OOM错误时自动dump下相关的.hprof文件,对该文件经过工具(好比MAT或者在线的perfma)进行分析;分析以后当找到占用内存比较大的对象对应的线程的业务代码(多是程序死循环,或者后端程序并发量比较大)

解决问题:若是是并发量比较大,就减小对后端程序的访问;经过Nginx增长机器,负载均衡,权重比例

案例三

发现问题:CPU负载太高

排查问题:命令:top jps jinfo jstat jmap 等这些命令灵活配合使用查看;多是服务程序处理压力过大

解决问题:具体看状况而论,能够集群部署、或者经过中间件(MQ、Kafka等)实现异步请求

案例四

发现问题:死锁

排查问题:能够经过 jstack 命令去查看相关线程锁的信息

解决问题:找到对应的业务代码,进行修改;或者使用zk、redis实现分布式锁

案例五

发现问题:线程池不够用了

排查问题:经过JDK的工具 jconcole jvisualvm 查看哪些线程得不到释放的

解决问题:适当的对后端代码优化,及时释放资源、合理的设置线程池中的参数(大小)

赵小胖我的博客

相关文章
相关标签/搜索