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

目录

核心思想

优化思考方向

压测环境准备

堆大小配置调优

调优前

调优后

分析结论

垃圾收集器配置调优

调优前

调优后

分析结论


        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.mzph.cn/news/831859.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

驾校考试宝典vip一点通驾考精简500题科目一四速记口诀c1答题技巧

下载地址&#xff1a;驾校考试宝典vip一点通驾考精简500题科目一四速记口诀c1答题技巧.zip 这份速记口诀考点总结 评分标准 和答题技巧&#xff0c;很详细&#xff0c;全科目速记口诀秘笈.pdf

QT中的容器

Qt中的容器 关于Qt中的容器类&#xff0c;下面我们来进行一个总结&#xff1a; Qt的容器类比标准模板库&#xff08;STL&#xff09;中的容器类更轻巧、安全和易于使用。这些容器类是隐式共享和可重入的&#xff0c;而且他们进行了速度和存储的优化&#xff0c;因此可以减少可…

mysql 指定根目录 迁移根目录

mysql 指定根目录 迁移根目录 1、问题描述2、问题分析3、解决方法3.1、初始化mysql前就手动指定mysql根目录为一个大的分区(支持动态扩容)&#xff0c;事前就根本上解决mysql根目录空间不够问题3.1.0、方法思路3.1.1、卸载mariadb3.1.2、下载Mysql安装包3.1.3、安装Mysql 8.353…

TouchGFX 总结

文章目录 使用中文字体多屏幕间交换数据UI to MCUMCU to UI API文档参考横竖屏切换 使用中文字体 添加一个textArea&#xff0c;默认的英文文本可见&#xff0c;输入中文字体后就看不见了&#xff0c;是因为这个默认的字体不支持中文&#xff0c;改一下字体就可以了&#xff1…

全方位解析Node.js:从模块系统、文件操作、事件循环、异步编程、性能优化、网络编程等高级开发到后端服务架构最佳实践以及Serverless服务部署指南

Node.js是一种基于Chrome V8引擎的JavaScript运行环境&#xff0c;专为构建高性能、可扩展的网络应用而设计。其重要性在于革新了后端开发&#xff0c;通过非阻塞I/O和事件驱动模型&#xff0c;实现了轻量级、高并发处理能力。Node.js的模块化体系和活跃的npm生态极大加速了开发…

网络基础-网络设备介绍

本系列文章主要介绍思科、华为、华三三大厂商的网络设备 网络设备 网络设备是指用于构建和管理计算机网络的各种硬件设备和设备组件。以下是常见的网络设备类型&#xff1a; 路由器&#xff08;Router&#xff09;&#xff1a;用于连接不同网络并在它们之间转发数据包的设备…

深入理解网络原理2----UDP协议

文章目录 前言一、UDP协议协议段格式&#xff08;简图&#xff09;校验和 二、UDP与TCP 前言 随着时代的发展&#xff0c;越来越需要计算机之间互相通信&#xff0c;共享软件和数据&#xff0c;即以多个计算机协同⼯作来完成业务&#xff0c;就有了⽹络互连。 一、UDP协议 协…

java发送请求-http和https

http和https区别 1、http是网络传输超文本协议&#xff0c;client---- http------ server 2、httpshttpssl证书&#xff0c;让网络传输更安全 &#xff0c;client---- httpssl------ server 3、ssl证书是需要客户端认可的&#xff0c;注意官方证书和jdk生成的证书的用户来使…

【Github】将github仓库作为图床使用

创建github仓库 首先创建一个github仓库专门用于存储图片&#xff0c;具体步骤如下&#xff1a; 1.点击新的仓库按钮 2.初始配置&#xff1a;随便填写一个仓库名&#xff1b;这里的仓库状态一定要是public公开的&#xff0c;不然后面访问不了图片 下载PicGo PicGo官网 在A…

获取淘宝商品销量数据接口

淘宝爬虫商品销量数据采集通常涉及以下几个步骤&#xff1a; 1、确定采集目标&#xff1a;需要明确要采集的商品类别、筛选条件&#xff08;如天猫、价格区间&#xff09;、销量和金额等数据。例如&#xff0c;如果您想了解“小鱼零食”的销量和金额&#xff0c;您需要设定好价…

【面试经典 150 | 数组】文本左右对齐

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;模拟 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容进行回顾…

C语言 | Leetcode C语言题解之第61题旋转链表

题目&#xff1a; 题解&#xff1a; struct ListNode* rotateRight(struct ListNode* head, int k) {if (k 0 || head NULL || head->next NULL) {return head;}int n 1;struct ListNode* iter head;while (iter->next ! NULL) {iter iter->next;n;}int add n…

【LeetCode刷题记录】230. 二叉搜索树中第K小的元素

230 二叉搜索树中第K小的元素 给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计一个算法查找其中第 k 个最小元素&#xff08;从 1 开始计数&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,1,4,null,2], k 1 输出&#xff1…

屏蔽罩材质和厚度对屏蔽效能的影响

​ 一&#xff0e;屏蔽效能的影响因素 屏蔽效能的影响因素主要有两个方面&#xff1a;屏蔽材料的特性和厚度&#xff1b;如下图所示&#xff0c;电磁波经过不同媒介时&#xff0c;会在分界面形成反射&#xff0c;穿过界面的电磁波一部分被反射回去&#xff0c;这部分能量损失…

音视频开发之旅——实现录音器、音频格式转换器和播放器(PCM文件转换为WAV文件、使用LAME编码MP3文件)(Android)

本文主要讲解的是实现录音器、音频转换器和播放器&#xff0c;在实现过程中需要把PCM文件转换为WAV文件&#xff0c;同时需要使用上一篇文章交叉编译出来的LAME库编码MP3文件。本文基于Android平台&#xff0c;示例代码如下所示&#xff1a; AndroidAudioDemo Android系列&am…

Leetcode—163. 缺失的区间【简单】Plus

2024每日刷题&#xff08;126&#xff09; Leetcode—163. 缺失的区间 实现代码 class Solution { public:vector<vector<int>> findMissingRanges(vector<int>& nums, int lower, int upper) {int n nums.size();vector<vector<int>> an…

docker部署nginx并配置https

1.准备SSL证书&#xff1a; 生成私钥&#xff1a;运行以下命令生成一个私钥文件。 生成证书请求&#xff08;CSR&#xff09;&#xff1a;运行以下命令生成证书请求文件。 生成自签名证书&#xff1a;使用以下命令生成自签名证书。 openssl genrsa -out example.com.key 2048 …

目标检测——铁路轨道故障数据集

一、重要性及意义 安全性保障&#xff1a;铁路作为重要的交通工具&#xff0c;其安全性能直接关系到乘客和货物的安全。铁路轨道故障&#xff0c;如裂缝、变形、错位、缺失紧固件等&#xff0c;都可能引发列车脱轨、倾覆等严重事故。因此&#xff0c;及时发现和修复这些故障&a…

【LLM第二篇】stable diffusion扩散模型、名词解释

最近在整理大模型的相关资料&#xff0c;发现了几个名词&#xff0c;不是很懂&#xff0c;这里整理一下&#xff1a; stable diffusion&#xff08;SD)模型&#xff1a; 扩散模型&#xff08;Diffusion model&#xff09;的一种&#xff0c;主要用于生成高质量的图像&#xf…

论文阅读笔记(AAAI 20)Order Matters

个人博客地址 注&#xff1a;部分内容参考自GPT生成的内容 论文笔记&#xff1a;Order Matters&#xff08;AAAI 20&#xff09; 用于二进制代码相似性检测的语义感知神经网络 论文:《Order Matters: Semantic-Aware Neural Networks for Binary Code Similarity Detection》…