springboot整合JMH做优化实战

news2024/11/26 10:34:23

       这段时间接手项目出现各种问题,令人不胜烦扰。吐槽下公司做项目完全靠人堆,大上快上风格注定留下一地鸡毛,修修补补不如想如何提升同事代码水准免得背锅。偶然看到关于JMH对于优化java代码的直观性,于是有了这篇文章,希望能帮到大家。

一:基础介绍文章

基准测试神器JMH——详解36个官方例子 - 知乎

这里介绍引入项目方式,各种基本注解用法,用例。比较全面,推荐大家学习

二:boot项目实用

注意事项:1.jdk版本大于9,最好使用的openJDK,其他的也行

                   2.做测试最好放在test包下,不影响正常项目使用

2-1 一般项目优化需求:

       一个简单方法,一个service接口(这个比较多。下面以这个为例)

场景1: 有个根据实例获取报警信息的接口  

        需求是要测试下,不同的多个实例对接口相应的影响,这里我分成1.2.3

直接test文件下新建

import com.chitic.things.device.api.request.monitor.AlarmSnsRequest;
import com.chitic.things.device.service.MonitorOnlineService;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.results.format.ResultFormatType;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

/**
 * 类功能说明: //
 *
 * @author Zhouxl
 * @date 2023/8/10 14:25
 */
@BenchmarkMode(Mode.AverageTime)  
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
@Warmup(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS)  //仿JVM进行预热行为,提高命中率(1s 3次)
public class BenchmarkTest {

    private ConfigurableApplicationContext context;
    private MonitorOnlineService onlineService;

    @Setup
    public void init() {
        // 这里的WebApplication.class是项目里的spring boot启动类
        context = SpringApplication.run(CommonApplication.class);
        // 获取需要测试的bean
        this.onlineService = context.getBean(MonitorOnlineService.class);
    }

    @Benchmark
    public  void one(){
        AlarmSnsRequest snsRequest =new AlarmSnsRequest();
        String str="test";
        snsRequest.setSns(Arrays.asList(str.split(",")));
        //测试接口方法
        onlineService.alarmPageBySns(snsRequest);
    }

    @Benchmark
    public  void two(){
        AlarmSnsRequest snsRequest =new AlarmSnsRequest();
        String str="test,test1";
        snsRequest.setSns(Arrays.asList(str.split(",")));
        //测试接口方法
        onlineService.alarmPageBySns(snsRequest);
    }
    @Benchmark
    public  void three(){
        AlarmSnsRequest snsRequest =new AlarmSnsRequest();
        String str="test,test1,test2";
        snsRequest.setSns(Arrays.asList(str.split(",")));
        //测试接口方法
        onlineService.alarmPageBySns(snsRequest);
    }


    @TearDown
    public void down() {
        context.close();
    }

    public static void main(String[]  args)throws RunnerException {
        Options opts = new OptionsBuilder()
                .include(BenchmarkTest.class.getSimpleName())
                .resultFormat(ResultFormatType.JSON)   //导出json 可通过 http://deepoove.com/jmh-visual-chart/ 对比
                //.addProfiler(StackProfiler.class)      //栈内存解析,主要分析方法的耗时情况
                // .addProfiler(GCProfiler.class)           //JVM GC的情况 各区的情况(G1的垃圾回收器情况)
                //.addProfiler(HotspotMemoryProfiler.class)   //使用HotSpot VM 进行内存占用分析
                .forks(1)    //进程数
                .build();
        new Runner(opts).run();

    }
}

测试结果:1个时耗时大概0.38s,2个和3个消耗会增加,但区别不大

可以在项目中对任意接口进行测试,还可以图形化接口比较,直接体现你的优化价值

JMH Visual Chart      生成的json引入这里生成图标

2-2  接口分析需求

场景2: 有个接口一直导致卡死或者内存OOM,代码是依托答辩,看了头晕

这里就需要借助JVM对堆栈内存,找出耗时情况,哪种应对哪个情况我已经上面列出来了:

package com.chitic.demo.controller.demo;

import com.chitic.demo.Application;
import com.chitic.demo.controller.HartCheck;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.profile.GCProfiler;
import org.openjdk.jmh.profile.HotspotMemoryProfiler;
import org.openjdk.jmh.profile.StackProfiler;
import org.openjdk.jmh.results.format.ResultFormatType;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;

import java.util.Arrays;
import java.util.concurrent.TimeUnit;

/**
 * 类功能说明: //对堆栈和GC内部
 *
 * @author Zhouxl
 * @date 2023/8/10 14:59
 */
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
@Warmup(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS)  //仿JVM进行预热行为,提高命中率(1s 3次)
public class JvmTest {

    private ConfigurableApplicationContext context;

    private HartCheck hartCheck;

    @Setup
    public void init() {
        // 这里的WebApplication.class是项目里的spring boot启动类
        context = SpringApplication.run(Application.class);
        // 获取需要测试的bean
        this.hartCheck = context.getBean(HartCheck.class);
    }

    @Benchmark
    public  void one(){
        //测试接口方法
        hartCheck.getUser();
    }



    @TearDown
    public void down() {
        context.close();
    }

    public static void main(String[]  args)throws RunnerException {
        Options opts = new OptionsBuilder()
                .include(JvmTest.class.getSimpleName())
                .addProfiler(StackProfiler.class)      //栈内存解析,主要分析方法的耗时情况
//                .addProfiler(GCProfiler.class)           //JVM GC的情况 各区的情况(G1的垃圾回收器情况)
//                .addProfiler(HotspotMemoryProfiler.class)   //使用HotSpot VM 进行内存分析
                .resultFormat(ResultFormatType.JSON)   //导出json 可通过 http://deepoove.com/jmh-visual-chart/ 对比
                .forks(1)    //进程数
                .build();
        new Runner(opts).run();

    }

}

2-2-1.addProfiler(StackProfiler.class)      //栈内存解析,主要分析方法的耗时情况

栈内存分析,主要看这些内容:

 就可以看到栈内耗时情况了,然后动手处理

2-2-2.addProfiler(GCProfiler.class) //JVM GC的情况 各区的情况(G1的垃圾回收器情况)

G1垃圾回收器的各种状态情况

2-2-3..addProfiler(HotspotMemoryProfiler.class)    //使用HotSpot VM 进行内存分析

展示数据和jstack的类似,能快速定位到哪些类占用内存,因为我的项目用的是graalvm17没办法用,只能各位自行探索了

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/859032.html

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

相关文章

浮动路由解决单点链路故障问题(第三十三课)

浮动路由解决单点链路故障问题(第三十三课) 理论来源于实践 1 路由的分类 2 直连路由: PC>ping 192.168.5.11Ping 192.168.5.11: 32 data bytes, Press Ctrl_C to break Request timeout! Request timeout! Request timeout! Request timeout! Request timeout!--- 192.16…

电脑ip地址怎么改 ip地址怎么改到别的城市

一、ip地址怎么改到别的城市 1.ip地址怎么改到别的城市,1、重启WIFI路由设备 一般手机或电脑在家或公司上网时都是接入到路由器的WIFI网络,再由路由器分配上网IP地址,如果要更换上网IP那么重启路由器设备后,路由器会向网络运营商进行宽带的重新拨号,此时手机或电脑设…

小程序自动化测试的示例代码

目录 背景 自动化 SDK 还原用户行为 总结 背景 上述描述看似简单,但是中间还是有些难点的,第一个难点就是如何在业务人员操作小程序的时候记录操作路径,第二个难点就是如何将记录的操作路径进行还原。 自动化 SDK 如何将操作路径还原这…

直接在html中引入Vue.js的cdn来实现一个简单的上传图片组件

摘要 当使用 Vue.js 的 CDN 来实现一个简单的上传图片组件时&#xff0c;你可以利用 Vue 的数据绑定和事件处理能力&#xff0c;结合 HTML 和 CSS&#xff0c;轻松地创建一个交互式的图片上传界面。以下是一个示例&#xff1a; 代码结构 index.html <!DOCTYPE html> &…

springcloud3 springcloud stream的学习以及案例

一 springcloud stream的作用 1.1 springcloud stream作用 stream屏蔽底层消息中间件的差异&#xff0c;降低切换成本&#xff0c;统一消息的编程模型。 stream中的消息通信模式遵循了“发布-订阅”模式。 1.2 Binder作用 通过定义绑定器Binder作为中间层&#xff0c;实现…

tomcat7.exe 启动闪退解决

标题tomcat7.exe 启动闪退解决 双击tomcat7.exe启动&#xff0c;但是出现闪退问题&#xff0c;无法启动tomcat 解决&#xff1a; 1.解决 tomcat7.exe 启动闪退解决 第一步&#xff1a;双击打开tomcat7w.exe 文件 如果出现 “指定的服务未安装。 Unable to open the service ‘…

编译iOS系统可用的FFmpeg

在进行编译之前&#xff0c;需要做一些准备工作安装必备文件&#xff1a; 1 安装 gas-preprocessor FFmpeg-iOS-build-script 自动编译脚本需要使用到 gas-preprocessor . 执行 sudo git clone https://github.com/bigsen/gas-preprocessor.git /usr/local/bin/gas sudo c…

工作每天都在用的 DNS 协议,你真的了解么?(文末有惊喜,别错过)

♥ 前 言 我们经常访问一些网址的时候&#xff0c;浏览器里输入类似于 www.baidu.com 这样的地址&#xff0c;那么在浏览器里输入这个地址---> 百度服务器给我们返回这个百度的页面&#xff0c;中间的过程是什么样的呢&#xff1f; 带着这个问题&#xff0c;我们一起来解…

HECI-Securtiy 防火墙路由技术

目录 一、防火墙路由基本原理 1.路由分类 2.路由优先级 3.路由查询先后顺序 4.静态路由基本原理 &#xff08;1&#xff09;指定出接口场景 &#xff08;2&#xff09;指定下一跳地址场景 5.静态路由与多出口 &#xff08;1&#xff09;主备备份 &#xff08;2&#…

FastSAM初体验,比SAM快50倍

一、FastSAM介绍 1.简介 由美国Meta公司提出的能够“分割一切”的视觉基础大模型SAM引起了较大影响&#xff0c;为探索通用视觉大模型提供了一个新的方向。 2023年6月22日&#xff0c;中科院自动化所的研究团队针对“分割一切”任务&#xff0c;提出了FastSAM方法。中科院自动…

Boost开发指南-4.3optional

optional 在实际的软件开发过程中我们经常会遇到“无效值”的情况&#xff0c;例如函数并不是总能返回有效值&#xff0c;很多时候函数正确执行了&#xff0c;但结果却不是合理的值。如果用数学语言来解释&#xff0c;就是返回值位于函数解空间之外。 求一个数的倒数&#xf…

Twitter霸屏:掌握社交流量密码

Twitter群推王发现&#xff0c;Twitter以其简短而有力的信息传递方式而著名&#xff0c;其中字符限制仅有280个。这意味着在Twitter的世界中&#xff0c;迅速高效的沟通至关重要。拥有约321亿月活跃用户的Twitter&#xff0c;成为塑造资源品牌知名度的强大平台。如今&#xff0…

PHP智能人才招聘网站mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP智能人才招聘网站 是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 下载地址 https://download.csdn.net/download/qq_41221322/88199392 视频演示 PH…

Alpine Ridge控制器使其具备多种使用模式 - 英特尔发布雷电3接口:竟和USB Type-C统一了

同时又因为这建立在Type-C的基础上&#xff0c;雷电3也将利用现有的标准Type-C线缆引入有源支持。当使用Type-C的线缆时&#xff0c;雷电的速度就降到了20Gbps全双工——这与普通的Type-C的带宽相同——这是为了成本牺牲了一些带宽。可以比较一下&#xff0c;Type-C线的成本只有…

基于Kubeadm部署k8s集群:下篇

继续上篇内容 目录 7、安装flannel 8、节点管理命令 三、安装Dashboard UI 1、部署Dashboard 2、开放端口设置 3、权限配置 7、安装flannel Master 节点NotReady 的原因就是因为没有使用任何的网络插件&#xff0c;此时Node 和Master的连接还不正常。目前最流行的Kuber…

【内网穿透】实现无公网IP远程连接Linux服务器并安装部署MongoDB数据库

【内网穿透】实现无公网IP远程连接Linux服务器并安装部署MongoDB数据库 ​ 憧憬Blog主页 在强者的眼中&#xff0c;没有最好&#xff0c;只有更好。 全栈开发领域优质创作者&#xff0c;阿里云专家博主 文章目录 【内网穿透】实现无公网IP远程连接Linux服务器并安装部署MongoDB…

智慧工地源码,Spring Cloud+ Vue+UniApp开发,微服务架构

智慧工地源码&#xff0c;智慧工地云平台源码 智慧工地APP源码 智慧工地的核心是数字化&#xff0c;它通过传感器、监控设备、智能终端等技术手段&#xff0c;实现对工地各个环节的实时数据采集和传输&#xff0c;如环境温度、湿度、噪音等数据信息&#xff0c;将数据汇集到云…

扎实推动产学研深入合作,携手共谋高质量发展新篇

近日&#xff0c;华南理工大学自动化学院胡跃明教授等一行4人莅临科东软件&#xff0c;双方就“产学研融合”进行会谈交流。在科东软件总经理余世清等人的陪同下&#xff0c;华工胡教授一行参观了科东软件展厅&#xff0c;对科东软件自主研发的Intewell工业实时操作系统及其在智…

xxx酒业有限责任公司突发环境事件应急预案WORD

导读&#xff1a;原文《xxx酒业有限责任公司突发环境事件应急预案word》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 目 录 1 总则 1.1 编制目的 1.2 编制…

JavaFx异常: Not on FX application thread; currentThread = Timer-0

我的定时器任务中有两个控件&#xff1a; FXML TextArea Display; FXML Label Label_Display; 执行下方代码会抛出&#xff1a;Exception in thread "Timer-0" java.lang.IllegalStateException: Not on FX application thread; currentThread Timer-0 Timer_tas…