听说jvm性能优化很难?今天我小试了一把!

陈树义      2022-06-12     353

关键词:

文章首发于公众号「陈树义」及个人博客 shuyi.tech,欢迎关注访问。

对于 Java 开发的同学来说,JVM 性能优化可以说是比较难掌握的知识点。这不仅因为 JVM 性能优化需要掌握晦涩难懂的 JVM 知识,还因为 JVM 性能优化很难有使用场景。这导致了许多人对 JVM 性能优化不熟悉,感觉就像是空中楼阁的天物一样不可触及。这几天工作中做了一次 JVM 性能优化,我想这对于 JVM 调优的初学者会有较大帮助。

背景

我们都知道 JVM 分为了新生代和老年代,并且我们在启动应用的时候都会配置对应的参数,为应用程序运行的 JVM 调整内存大小。但我们都知道,很多时候我们都只是大致估计一个数,随便填填,然后就上线了。

作者所在的公司同样存在这种情况,JVM 内存大小基本上都设得挺大的,毕竟内存大总比内存溢出好,因此就造成了不少的内存浪费。所以作者收到的任务就是对所有的应用进行一次排查,调整合适的内存参数,优化 JVM 的性能。

调优实战

要对应用进行 JVM 性能调优,那么首先得知道其运行的情况。这就像去医院看医生,去开药之前需要医生先望闻问切一样。在 Java 中,有很多方式可以观察到 JVM 的内部情况,例如 JDK 提供的各种命令工作。作者所在公司使用的是 Prometheus 进行监控,因此我们可以直接在 Prometheus 上看到应用的 JVM 运行情况。

文章首发于公众号「陈树义」及个人博客 shuyi.tech,欢迎关注访问。

Prometheus 面板中与 JVM 相关的主要有四块内容:JVM Misc、JVM Memory Pools(Heap)、JVM Memory Pools(Non-Heap)、Garbage Collection。其中与我们此次较为相关的主要是:JVM Memory Pools(Heap)和 Garbage Collection。

JVM Memory Pools(Heap) 展示 JVM 堆内存的使用情况,主要包括了新生代的 Survivor 区、Eden Space 区、老年代。

JVM Memory Pools(Heap)

Garbage Collection 展示 JVM 的垃圾回收情况,主要包括垃圾回收频率(ops 表示一秒回收几次,一般 0.5 是比较合理的值)、每次 GC 停顿时长(一般 80ms 以下是合理值)、分配到新生代/晋升老年代的内存。

Garbage Collection

我们要进行 JVM 性能优化,那么最简单的一个方法就是观察 Garbage Collection 的 GC 频率以及停顿时间,我们大致就能判断出应用的内存利用效率。之后根据这两个值的实际情况,将其调整到合理的范围内,提高 JVM 的利用率。

如果一个应用的 GC 频率只有 0.02,即每秒 GC 0.02 次,那么需要 50 秒才 GC 一次,那么其 GC 频率是很低的。这时候很可能是分配了较大的新生代空间,这使得其很久才需要 GC 一次。这时候我们再看看其停顿时间,如果停顿时间也很短的话,那我们就可以判定该应用的内存有优化的空间。

文章首发于公众号「陈树义」及个人博客 shuyi.tech,欢迎关注访问。

在这种情况下,一般都是缩小分配的新生代的空间。新生代空间一旦变小了,那么其分配完的时间就会缩减。一旦空间被分配完,那么就会启动进行 GC 操作。我们就是通过调整 JVM 的内存空间,来提高 GC 的频率,从而使其处于一个合理的空间。

在进行内存空间调整的时候,为了避免内存剧烈波动导致的问题,一般我们都是小步快跑地一点点调整。先调整一点试一试,没太大问题之后再调整到目标值。 毕竟是生产环境,要是出了什么叉子,那就得提桶跑路了,还是谨慎为好!

看到这里,想必大家应该也知道怎么做了。接下来无非就是调整 JVM 内存空间的三个参数(-Xmx -Xms -Xmn),使 GC 频率与 GC 停顿时间处于合理的区间。

应用层面优化

除了 GC 频率、GC 停顿时间,我们还能从应用的类型来分析 JVM 的内存消耗情况。

例如对于接口类型的系统来说,很多请求都是 1 秒中之内就结束。对于这种类型的请求,他们进入应用时会分配内存,结束时内存就会立刻被回收,留存下来的对象很少。这种应用的 JVM 内存情况大概是这样的:新生代消耗比较大,并且随着周期性回收内存,但老年代的内存消耗则更小。对于那些持续性处理的应用,例如持续时间长的应用处理。因为其存活时间较久,所以可能会有更多的对象晋升到老年代,因此老年代的内存消耗就比较大。

通过观察 JVM 年轻代与老年代的内存消耗情况,再结合应用本身的特性,我们可以发现应用中不合理的地方,再对应用进行针对性的优化。例如:应用某个地方每次都会存储大量的临时数据到内容中,这样就造成了 JVM 可能爆发 GC,从而导致应用卡顿。

总结

总结一下本篇文章的调优方法:通过观察 GC 频率和停顿时间,来进行 JVM 内存空间调整,使其达到最合理的状态。调整过程记得小步快跑,避免内存剧烈波动影响线上服务。 这其实是最为简单的一种 JVM 性能调优方式了,可以算是粗调吧。但 JVM 性能调优还有更多、更详细的参数,后续有机会我们再聊聊。

此外,通过观察 JVM 年轻代与老年代的情况,也可以帮助我们对应用进行针对性的优化,从而提升应用本身的性能。

如果你之前没了解过 JVM 的基础理论知识,那么你可能看不懂这篇文章。那么我推荐你看看我的「JVM 基础入门系列」,文章由浅入深、循序渐进,可以让你对 JVM 有个感性的理解。看完之后再来看这篇文章,你肯定有种豁然开朗的感觉!

JVM 基础入门系列传送门:JVM 基础入门系列 - 陈树义的博客

关于 JVM 性能调优,就分享到这里吧。

谢谢大家的阅读。如果文章对你有帮助,点个 「在看」 ,或者分享到朋友圈

文章首发于公众号「陈树义」及个人博客 shuyi.tech,欢迎关注访问。

jvm篇之牛刀小试年轻代参数优化探索

前言在JVM篇之牛刀小试(一)我们谈到了关于年轻代参数的问题,就是当我没有设置-Xmn的时候,gc时间居然比我设置了500m的时候,时间还短,然后当时我就停止了探索。后来我在公司飞书文档写了一篇文... 查看详情

jvm性能优化,第2部分:编译器jvm

...家参考学习,如有不足之处,欢迎补充!Java编译器在JVM性能优化系列的第二篇文章中占据中心位置。EvaAndreasson介绍了不同种类的编译器,并比较了客户端,服务器和分层编译的性能结果。最后,她概述了常见的JVM优化,例如消... 查看详情

推荐:java性能优化系列集锦

Java性能问题一直困扰着广大程序员,由于平台复杂性,要定位问题,找出其根源确实很难。随着10多年Java平台的改进以及新出现的多核多处理器,Java软件的性能和扩展性已经今非昔比了。现代JVM持续演进,内建了更为成熟的优... 查看详情

jvm调优总结

...遇到服务的QPS在压测的时间比较低的情况。于是就开始了性能优化之旅,这个过程是很是曲折。一开始的时候认为是服务的业务逻辑比较多,大部分的时间都花在优化业务逻辑,减少与其他服务和数据库等接口的调用,使用缓存... 查看详情

day800.jvm内存分配优化-java性能调优实战(代码片段)

...调优都是有目标性的,JVM内存分配调优也一样。没有性能问题的时候,自然不会随意改 查看详情

day800.jvm内存分配优化-java性能调优实战(代码片段)

...调优都是有目标性的,JVM内存分配调优也一样。没有性能问题的时候,自然不会随意改 查看详情

jvm篇之牛刀小试

前言很久没有写博客了,沉寂了一段时间,那是因为我在闭关啃书,哈哈。JVM作为高级开发所需要具备的能力,在以往面试的时候都会遇到,让我印象很深刻的,就是面试欢聚的shopline,好家伙,面... 查看详情

jvm篇之牛刀小试(ps:之前请教我的小伙子校招去了字节~)

闲聊最近在学jvm,当然这是一个持续过程,知行合一对吧,学习之后立马去应用,才能验证你学到是不是有用的东西。大家看过我上一篇写的博客么,之前在csdn请教过我的一个小伙子,最近我看他已经入... 查看详情

小师妹学jvm之:cacheline对代码性能的影响(代码片段)

...现象小师妹:F师兄,之前你讲了那么多JVM中JIT在编译中的性能优化,讲真的,在工作中我们真的需要知道这些东西吗?知道这些东西对我们的工作有什么好处吗 查看详情

火遍github的这份jvm性能优化实践手册,首发下载量就已过百万

本书从实验科学的角度探讨了Java性能优化的方方面面,重点阐述了**的实用JVM性能调优策略、工具和技巧。通过本书,我们不仅可以了解Java原理和技术如何充分利用现代硬件和操作系统、衡量Java性能的陷阱以及微基准测试的弊... 查看详情

在线时序图

   今天想画时序图,之前流程图一般我使用OmniGraffle,也是非常强大;but对款软件如何画时序图还是不怎么熟悉;因此在网上找了在线时序图;结果人意外的找到了在线时序图软件websequencediagrams;自己小试了一把:tit... 查看详情

jmh-java代码性能测试的终极利器必须掌握(务必收藏)!(代码片段)

Java性能测试难题现在的JVM已经越来越为智能,它可以在编译阶段、加载阶段、运行阶段对代码进行优化。比如你写了一段不怎么聪明的代码,到了JVM这里,它发现几处可以优化的地方,就顺手帮你优化了一把。这... 查看详情

jvm篇之牛刀小试(ps:之前请教我的小伙子校招去了字节~)

...灰度,就指点了一下在寒冬里,不要丧失斗志JVM优化一:G1打开并发标记在G1的垃圾回收流程中,并发标记是不会stoptheworld,依靠初始标记的GCROOT相关的根对象,然后在并发标记的时候,找到对应的引用... 查看详情

jquery性能优化

...解"如何用好jQuery"。我主要参考了AddyOsmani的PPT《提高jQuery性能的诀窍》(jQueryProvenPerformanceTipsAndTricks)。他是jQuery开发团队的成员,具有一定的权威性,提出的结论都有测试数据支持,非常有价 查看详情

jvm性能优化

 java应用程序是应用在JVM上的,你们对JVM又有多少了解呢?JVM将内存分为三部分:NEW(年轻代)、Tenured(年老代)、Perm(永久代)。   (1)年轻代:用来存放java分配的新对象。   (2)年老代:经过垃圾... 查看详情

书籍推荐:《实战java虚拟机——jvm故障诊断与性能优化》下载

...在实践和调优方面,重点介绍了Java的堆、栈分析方法,性能调优的一般思路、手段和工具。此外,还详细介绍了虚拟机内有关“锁”的实现以及优化方法。作为对虚拟机的深入了解,本书还将详细介绍Java类的基 查看详情

jvm性能调优

  JVM技术图谱 性能调优性能调优包含多个层次,比如:架构调优、代码调优、JVM调优、数据库调优、操作系统调优等。架构调优和代码调优是JVM调优的基础,其中架构调优是对系统影响最大的。性能调优基本上按照以... 查看详情

性能优化系列三:jvm优化1

一、几个基本概念GCRoots对象都有哪些所有正在运行的线程的栈上的引用变量。所有的全局变量。所有ClassLoader。。。1.SystemClass.2.JNILocal3.JNIGlobal4.ThreadBlock5.BusyMonitor6.JavaLocal7.NativeStack8.Unfinalized9.Unreachable10.JavaStackFrame11.Unknow 查看详情