Java高阶私房菜:JVM性能优化案例及讲解

embedded/2024/12/23 1:14:00/

目录

核心思想

优化思考方向

压测环境准备

堆大小配置调优

调优前

调优后

分析结论

垃圾收集器配置调优

调优前

调优后

分析结论


        JVM性能优化是一项复杂且耗时的工作,该环节没办法一蹴而就,它需要耐心雕琢,逐步优化至理想状态。“性能调优” 该词是那么的高大上,但其实工作中因投入产出比(ROI)的关系,我们经常不会过多投入到这个工作中,而是更多投入到其他ROI更高的环节上,或有金主爸爸的允许下直接升级设备/服务器的性能,那为什么我们还要大费周章的去讲JVM呢?因为JVM性能调优是性能提升的最后一步,当所有环节都无法加工优化时,就需要在这个环节操刀了,其次就是架不住面试馆的会问呀。

核心思想

        任何java业务做性能优化,都需要掌握JVM内部的工作机制和应用程序的特性,当某个节点性能优化接近极致的时候,就需要从局部跳到宏观层面进行分析,考虑自己和团队的ROI。另外缺少业务场景的性能优化都是浮云。

        当面试官问到如何开始JVM调优时,就不要直接的回答自己是怎么进行JVM调参的,而是先了解他的意图、基本信息,是否有其他方向优化的可能等等,才能将答案回答到面试官的点中去。

优化思考方向

JVM优化

  • 监控JVM性能:对JVM的运行情况进行监控,以了解应用程序的瓶颈和性能瓶颈,可以使用JVM自带的工具,如jstat、jmap、jstack等,或者第三方工具,如VisualVM、JProfiler等。
  • 压测基准指标:对程序进行压测,得出接口对应的吞吐量、响应时间等。外部现象:对用户体验来说,就是响应速度,可以用压测工具jmeter进行压测得出相关性能指标;内部现象:分析GC情况,是JVM性能调优的重要因素,需要掌握GC的工作机制和GC日志的含义,可以使用JVM自带的GC日志或者第三方工具,如GCEasy等来分析GC情况,了解GC的频率、时间、内存占用等情况。
  • 调整JVM参数:通过调整堆大小、GC算法、线程池大小等参数来提高应用程序的性能。另外需要注意的点是不同的应用程序和环境可能需要不同的JVM参数配置,比如IO密集型和CPU密集型应用。

二次压测分析

        通过调整jvm参数后,二次压测看性能指标提升还是下降。内部检测通过分析GC日志,看吞吐量,GC次数和停顿时间变化等。外部监测主要看接口对应的吞吐量、响应时间长短等。

其他优化方向

  • 优化代码:通过避免不必要的对象创建、减少同步操作、使用缓存等方式来优化代码。但需注意的是代码优化应该遵循“先正确,再优化”的原则,不应该牺牲代码的可读性和可维护性

  • 使用并发编程:使用多线程、线程池等方式来提高并发性能,比如调整线程池的队列长度,存活线程数量等,但需要注意的是并发编程需要考虑线程安全和锁竞争等问题,需要进行正确的设计和实现。

  • 使用缓存:可以使用本地缓存、分布式缓存等方式来提高数据访问性能,但需要注意的是缓存需要考虑缓存一致性和缓存失效等问题,需要进行正确的设计和实现。

  • 避免IO阻塞:使用异步IO、NIO等方式来提高IO性能,例如前面讲解的CompletableFuture异步任务编排,但需要注意的是IO编程需要考虑并发性和可靠性等问题,需要进行正确的设计和实现。

传送门:Java高阶私房菜:快速学会异步编程CompletableFuture-CSDN博客

  • 分布式+集群技术:使用负载均衡+集群技术,提升单节点的处理能力

  • 其他技术...

压测环境准备

测试程序准备

        SpringBoot 编写的jar的程序,接口一个返回随机组成的100个以内的对象的list (使用JDK17)

相关代码

@RestController
@RequestMapping("/api/product")
public class ProductController {@RequestMapping("query")public Map<String, Object> query() throws InterruptedException {int num = (int) (Math.random() * 100) + 1;Byte[] bytes = new Byte[5 * 1024 * 1024];List<Product> productList = new ArrayList<>();for (int i = 0; i < num; i++) {Product product = new Product();product.setPrice((int) Math.random() * 100);product.setTitle("csdn文章,文章编号" + i);productList.add(product);}Thread.sleep(5);Map<String, Object> map = new HashMap<>(16);map.put("data", productList);return map;}}public class Product {private int price;private String title;public Product() {}public Product(int price, String title) {this.price = price;this.title = title;}}

Jmeter压测工具准备

        测试计划 200并发,循环500次,主要测试两个场景:

  • 案例一:堆大小配置,FullGC次数的性能影响

  • 案例二:不同垃圾收集器对性能的影响

有条件的可以Linux操作系统测试,测试机和压测机器分开,采用内网测试,尽量减少影响因素

堆大小配置调优

调优前

性能优化初始值

-Xms1g
-Xmx1g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:G1HeapRegionSize=32M
-XX:ActiveProcessorCount=8
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=heapdump.hprof
-XX:+PrintCommandLineFlags 
-Xlog:gc=info:file=portal_gc.log:utctime,level,tags:filecount=50,filesize=100M

外部指标 

内部指标

 

调优后

JVM参数调整

        通过调整JVM的堆大小看吞吐量

-Xms8g
-Xmx8g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:G1HeapRegionSize=32M
-XX:ActiveProcessorCount=8
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=heapdump.hprof
-XX:+PrintCommandLineFlags 
-Xlog:gc=info:file=portal_gc.log:utctime,level,tags:filecount=50,filesize=100M

外部指标

内部指标

 

分析结论

        不同堆空间大小堆系统影响比较大,高内存则可以减少GC次数,得到比较高的吞吐量。测试的时候可以每2G的内存增长进行测试,增加到一定堆大小后,ROI会逐步下降,找到一定的峰值即可。

垃圾收集器配置调优

调优前

性能优化初始值

-Xms1g
-Xmx1g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:G1HeapRegionSize=32M
-XX:ActiveProcessorCount=8
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=heapdump.hprof
-XX:+PrintCommandLineFlags 
-Xlog:gc=info:file=portal_gc.log:utctime,level,tags:filecount=50,filesize=100M

外部指标

内部指标

 

调优后

JVM参数调整

通过调整JVM的垃圾收集器看吞吐量

-Xmx1g -Xms1g -XX:+UseParallelGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdump.hprof -XX:+PrintCommandLineFlags  -Xlog:gc=info:file=portal_gc.log:utctime,level,tags:filecount=50,filesize=100M

外部指标 

 内部指标

分析结论

        不同垃圾回收器对程序的吞吐量影响,同等条件下G1收集器会比Parallel收集器强,吞吐量更高,响应时间更低,完成同等数量的请求耗时更少,G1和ZGC等更适合大内存的情况业务,尤其是16G内存以上的业务。


http://www.ppmy.cn/embedded/41223.html

相关文章

科技查新中医学科研项目查新点如何确立与提炼?案例讲解

一、前言 医学科技查新包括立项查新和成果查新两个部分&#xff0c;其中医学立项查新&#xff0c;它是指在医学科研项目申报开题之前&#xff0c;通过在一定范围内进行该课题的相关文献检索 ( 可以根据项目委托人的具体要求&#xff0c;进行国内检索或者进行国外检索 ) &#x…

LeetCode2352相等行列对

题目描述 给你一个下标从 0 开始、大小为 n x n 的整数矩阵 grid &#xff0c;返回满足 Ri 行和 Cj 列相等的行列对 (Ri, Cj) 的数目。如果行和列以相同的顺序包含相同的元素&#xff08;即相等的数组&#xff09;&#xff0c;则认为二者是相等的。 解析 针对题目给出的数量级…

LVS负载均衡超详细入门介绍

LVS 一、LVS入门介绍 1.1.LVS负载均衡简介 1.2.负载均衡的工作模式 1.2.1.地址转换NAT&#xff08;Network Address Translation&#xff09; 1.2.2.IP隧道TUN&#xff08;IP Tunneling&#xff09; 1.2.3.直接路由DR&#xff08;Direct Routing&#xff09; 1.3.…

(论文阅读-分析引擎)Modin

一、简介 目标是在不改变的Dataframe语义的情况下支持可扩展的dataframe操作。 什么是机会主义评价&#xff1f;Opportunistic Evaluation&#xff1f; Exploratory data analysis&#xff08;EDA&#xff09;&#xff1a;总结、理解并从数据集中获取价值的过程。 MPI&#…

Java Swing游戏开发学习27

内容来自RyiSnow视频讲解 这一节讲的是Equip & Use Items装备与使用物品。 前言 实现捡起物品、切换武器装备、使用物品。 修复问题 当光标在物品栏&#xff08;背包&#xff09;中移动到没有物品的格子中的时候&#xff0c;使装备介绍子窗口不可见&#xff0c;反之可见…

开源工时填报管理系统部署

1、工时管理系统的重要性 对于企业来说,工时管理往往和生产效率、成本、项目成率挂钩,所以其重要性是不容忽视的,并且主要体现在以下几个方面: 提高生产效率:通过精确记录员工的工作时间,工时管理系统一定程度可以帮助企业更好地了解员工的工作状态和效率。这将有助于企…

7nm项目之模块实现——02 Placeopt分析

一、Log需要看什么 1.log最后的error 注意&#xff1a;warnning暂时可以不用过于关注&#xff0c;如果特别的warning出现问题&#xff0c;在其他方面也会体现 2.run time 在大型项目实际开发中&#xff0c;周期一般较长&#xff0c;可能几天过这几周&#xff0c;所以这就需要…

使用curl命令查看服务器端口开放情况

目录 1.ssh端口 22 2.mysql数据库端口 3306 3.web应用端口 &#xff08;Jellyfin 8082&#xff09; &#xff08;wordpress 8088&#xff09; &#xff08;tomcat 8080&#xff09; 4.不存在的端口 5.被防火墙阻挡的端口 1.ssh端口 22 curl -v 10.10.10.205:22 curl…