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.mfbz.cn/a/592588.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Qt服务器端与客户端交互

Qt做客户端与服务器端交互第一步引入network 第一步引入network后继续编程首先界面设计 创建server和socket 引入QTcpServer&#xff0c;QTcpSocket MainWindow.h代码如下 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QTcpServer&…

EPAI手绘建模APP演示板、材质编辑器、样式编辑器

(11) 更多 图 74 更多工具栏 ① 演示板&#xff1a;打开关闭演示板。演示板用来显示从设备导入的模型图纸图片或者打开模型建模教程网页&#xff0c;是建模过程中一个辅助功能。有些设备有小窗口功能有些没有&#xff0c;对于没有小窗口功能的设备&#xff0c;通过演示板能够在…

智慧旅游引领旅游行业创新发展:借助智能科技的力量,实现旅游资源的优化配置和高效利用,推动旅游行业的转型升级和可持续发展

目录 一、引言 二、智慧旅游的定义与特点 1、信息化程度高 2、智能化服务丰富 3、互动性强 4、个性化服务突出 5、可持续性发展 三、智慧旅游在旅游行业创新发展中的作用 &#xff08;一&#xff09;优化旅游资源配置 &#xff08;二&#xff09;提升旅游服务质量 &…

【吃透Java手写】- Spring(上)-启动-扫描-依赖注入-初始化-后置处理器

【吃透Java手写】Spring&#xff08;上&#xff09;启动-扫描-依赖注入-初始化-后置处理器 1 准备工作1.1 创建自己的Spring容器类1.2 创建自己的配置类 ComponentScan1.3 ComponentScan1.3.1 Retention1.3.2 Target 1.4 用户类UserService Component1.5 Component1.6 测试类 2…

HCIA-题目解析1

0x00 前言 遇到这样一道题,这种题目对于我来说还是比较复杂的,所以记录一下。主要还是和熟练度有关系。 0x01 题目 路由器RouterID邻居关系如下,下列说法正确的是 A:本路由器和Router-lD为10.0.3.3的路由器不能直接交换链路状态信息 B:DR路由器的Router-lD为10.0.1.2 C:…

机器学习:基于K-近邻(KNN)、高斯贝叶斯(GaussianNB)、SVC、随机森林(RF)、梯度提升树(GBDT)对葡萄酒质量进行预测

前言 系列专栏&#xff1a;机器学习&#xff1a;高级应用与实践【项目实战100】【2024】✨︎ 在本专栏中不仅包含一些适合初学者的最新机器学习项目&#xff0c;每个项目都处理一组不同的问题&#xff0c;包括监督和无监督学习、分类、回归和聚类&#xff0c;而且涉及创建深度学…

Finder Windows for Mac:双系统窗口,一键切换!

Finder Windows for Mac是一款专为Mac用户设计的实用工具&#xff0c;它模拟了Windows系统的窗口管理功能&#xff0c;让Mac用户也能享受到类似Windows的窗口操作体验。这款软件的主要功能是提供一个浮动面板&#xff0c;帮助用户随时即时访问打开的Finder窗口列表&#xff0c;…

力扣每日一题106:从中序与后序遍历序列构造二叉树

题目 中等 相关标签 相关企业 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7], postorder …

在线协作,开源的设计和原型创作平台:penpot

penpot&#xff1a;面向团队&#xff0c;设计自由- 精选真开源&#xff0c;释放新价值。 概览 Penpot 是一款专为跨职能团队量身定制的开源设计软件&#xff0c;与行业领先的 Figma 齐名&#xff0c;提供了一个强大而灵活的在线设计解决方案。其最大的亮点在于&#xff0c;用户…

Qt与MySQL连接

QT连接Mysql数据库&#xff08;详细成功版&#xff09;-CSD N博客 我的MySQL是64位的&#xff0c;所以我的Qt的套件也需要是64位的 遇到的问题&#xff1a; &#xff08;available drivers中已经有QMYSQL QMYSQL3&#xff0c;还是not loaded&#xff09; QSqlDatabase: QMYS…

SQL注入-基础知识

目录 前言 一&#xff0c;SQL注入是什么 二&#xff0c;SQL注入产生的条件 三&#xff0c;学习环境介绍 四、SQL注入原理 五&#xff0c;SQL中常用的函数 六&#xff0c;关于Mysql数据库 前言 在网络安全领域中&#xff0c;sql注入是一个无法被忽视的关键点&#xff0c…

安卓 app icon大小 安卓app界面尺寸大小

移动应用的界面设计画布尺寸设计多大&#xff08;特别是Android&#xff09;、图标和字体大小怎么定、需要设计多套设计稿么、如何切图以配合开发的实现&#xff1f; 本篇将结合iOS和android官方的设计规范、搜集的资料以及工作中的摸索&#xff0c;来分享移动应用界面设计中的…

【C++】STL — List的接口讲解 +详细模拟实现

前言&#xff1a; 本章我们将学习STL中另一个重要的类模板list… list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。list的底层是带头双向循环链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xf…

Conntroller内存马详解(2)

流程分析 获取context 第一种&#xff1a;getCurrentWebApplicationContext() // getCurrentWebApplicationContext方法获得的是一个XmlWebApplicationContext实例类型的Root WebApplicationContext。WebApplicationContext context ContextLoader.getCurrentWebApplication…

docker部署nginx并实现https

文章目录 docker部署nginx并实现https1、服务器环境2、安装docker3、准备证书4、准备nginx配置文件和dockerfile文件5、创建nginx镜像与容器6、验证访问 docker部署nginx并实现https 1、服务器环境 [rootliuyanfen12 ~]#systemctl stop firewalld [rootliuyanfen12 ~]#setenf…

Flutter笔记:美工设计.导出视频到RIVE

Flutter笔记 美工设计.导出视频到RIVE - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28…

RabbitMQ之顺序消费

什么是顺序消费 例如&#xff1a;业务上产生者发送三条消息&#xff0c; 分别是对同一条数据的增加、修改、删除操作&#xff0c; 如果没有保证顺序消费&#xff0c;执行顺序可能变成删除、修改、增加&#xff0c;这就乱了。 如何保证顺序性 一般我们讨论如何保证消息的顺序性&…

【Linux】进程的隔离和控制:namespace 隔离、cgroup 控制

文章目录 五、namespace 隔离dd -- 读取、转换并输出数据mkfs -- 格式化文件系统df -- 显示文件系统磁盘使用情况mount -- 加载文件系统到指定的加载点unshare -- 创建子进程&#xff0c;同时与父程序不共享namespace一个 demo 六、cgroup(Control Group) 相关命令pidstat -- 监…

【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…

2024年深圳杯东三省联赛数模竞赛A题代码改进-更加合理的结果

4月下旬深圳杯开赛后第二天就推出了完整版的论文&#xff0c;经过长达半个月大家再售后群的讨论分析&#xff0c;我们又重新对之前思路下写的代码进行了改进。本次改进的结果&#xff0c;我们特地参考了网上一些常见的火箭及其相关的级别分离高度&#xff1a;&#xff08;我们的…