springboot整合JMH做优化实战

       这段时间接手项目出现各种问题,令人不胜烦扰。吐槽下公司做项目完全靠人堆,大上快上风格注定留下一地鸡毛,修修补补不如想如何提升同事代码水准免得背锅。偶然看到关于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;@Setuppublic void init() {// 这里的WebApplication.class是项目里的spring boot启动类context = SpringApplication.run(CommonApplication.class);// 获取需要测试的beanthis.onlineService = context.getBean(MonitorOnlineService.class);}@Benchmarkpublic  void one(){AlarmSnsRequest snsRequest =new AlarmSnsRequest();String str="test";snsRequest.setSns(Arrays.asList(str.split(",")));//测试接口方法onlineService.alarmPageBySns(snsRequest);}@Benchmarkpublic  void two(){AlarmSnsRequest snsRequest =new AlarmSnsRequest();String str="test,test1";snsRequest.setSns(Arrays.asList(str.split(",")));//测试接口方法onlineService.alarmPageBySns(snsRequest);}@Benchmarkpublic  void three(){AlarmSnsRequest snsRequest =new AlarmSnsRequest();String str="test,test1,test2";snsRequest.setSns(Arrays.asList(str.split(",")));//测试接口方法onlineService.alarmPageBySns(snsRequest);}@TearDownpublic 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;@Setuppublic void init() {// 这里的WebApplication.class是项目里的spring boot启动类context = SpringApplication.run(Application.class);// 获取需要测试的beanthis.hartCheck = context.getBean(HartCheck.class);}@Benchmarkpublic  void one(){//测试接口方法hartCheck.getUser();}@TearDownpublic 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.mzph.cn/news/31081.shtml

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

相关文章

11款UML/SysML建模工具更新(2023.7)Papyrus、UModel……

DDD领域驱动设计批评文集 欢迎加入“软件方法建模师”群 《软件方法》各章合集 最近一段时间更新的工具有: 工具最新版本:drawio-desktop 21.6.5 更新时间:2023年7月22日 工具简介 开源绘图工具,用Electron编写,…

uniapp文件下载并预览

大概就是这样的咯&#xff0c;文件展示到页面上&#xff0c;点击文件下载并预览该文件&#xff1b; 通过点击事件handleDownLoad(file.path)&#xff0c;file.path为文件的地址&#xff1b; <view class"files"><view class"cont" v-for"(…

PPO和文本生成

策略梯度 策略梯度&#xff08;Policy Gradient&#xff09;方法梯度的计算如下&#xff1a; E ( a t , s t ) ∈ π θ [ A ^ t ∇ θ log ⁡ π θ ( a t ∣ s t ) ] \mathbb E_{(a_t,s_t) \in \pi_\theta}[\hat A_t \nabla_ \theta \log \pi_\theta(a_t | s_t)] E(at​,st…

Nginx的重定向

URI&#xff1a;统一资源标识符&#xff0c;是一种字符串标识&#xff0c;主要是用于标识抽象的或者是物理资源&#xff08;主要是指一些文件视频等等&#xff09; 常用的Nginx正则表达式 ^ 匹配输入字符串的起始位置&#xff08;以......开头&#xff09; $ 匹配输入…

FreeRTOS( 任务与中断优先级,临界保护)

资料来源于硬件家园&#xff1a;资料汇总 - FreeRTOS实时操作系统课程(多任务管理) 目录 一、中断优先级 1、NVIC基础知识 2、FreeRTOS配置NVIC 3、SVC、PendSV、Systick中断 4、不受FreeRTOS管理的中断 5、STM32CubeMX配置 二、任务优先级 1、任务优先级说明 2、任务…

【LeetCode】144. 二叉树的前序遍历、94. 二叉树的中序遍历、145. 二叉树的后序遍历

作者&#xff1a;小卢 专栏&#xff1a;《Leetcode》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 144. 二叉树的前序遍历 144. 二叉树的前序遍历 题目&#xff1a; 给你二叉树的根节点 root &…

保姆级Arcgis安装图文安装教程

参考视频&#xff1a;【钟老师arcGIS从放弃到入门】02软件下载与安装_哔哩哔哩_bilibili 安装包在视频简介中有 注释&#xff1a;安装过程中有犯错误&#xff0c;请耐心看完一遍再跟着操作 &#xff08;一&#xff09;安装包下载 下载视频中分享的压缩包(压缩包密码&#x…

window下部署Yapi接口管理系统部署总结

window下部署Yapi接口管理系统部署总结 YApi 是高效、易用、功能强大的 api 管理平台&#xff0c;旨在为开发、产品、测试人员提供更优雅的接口管理服务。可以帮助开发者轻松创建、发布、维护 API&#xff0c;YApi 还为用户提供了优秀的交互体验&#xff0c;开发人员只需利用平…

后端开发8.品牌模块

概述 简介 效果图 数据库设计 DROP TABLE IF EXISTS `goods_brand`;CREATE TABLE `goods_brand` ( `goodsBrandId` int(11) NOT NULL AUTO_IN

04-4_Qt 5.9 C++开发指南_时间日期与定时器

文章目录 1. 时间日期相关的类2. 源码2.1 可视化UI设计2.2 dialog.h2.3 dialog.cpp 1. 时间日期相关的类 时间日期是经常遇到的数据类型&#xff0c;Qt 中时间日期类型的类如下。 QTime:时间数据类型&#xff0c;仅表示时间&#xff0c;如 15:23:13。 QDate:日期数据类型&…

【资料分享】全志科技T507-H工业核心板规格书

1 核心板简介 创龙科技SOM-TLT507是一款基于全志科技T507-H处理器设计的4核ARM Cortex-A53全国产工业核心板&#xff0c;主频高达1.416GHz。核心板CPU、ROM、RAM、电源、晶振等所有元器件均采用国产工业级方案&#xff0c;国产化率100%。 核心板通过邮票孔连接方式引出MIPI C…

QGIS开发五:使用UI文件

前面我们说了在创建项目时创建的是一个空项目&#xff0c;即不使用 Qt 提供的综合开发套件 Qt Creator&#xff0c;也不使用 Qt Visual Studio Tools 这类工具。 但是后面发现&#xff0c;如果我想要有更加满意的界面布局&#xff0c;还是要自己写一个UI文件&#xff0c;如果不…

深度对话|如何设计合适的网络经济激励措施

近日&#xff0c;我们与Mysten Labs的首席经济学家Alonso de Gortari进行了对话&#xff0c;讨论了如何在网络运营商和参与者之间找到激励措施的平衡&#xff0c;以及Sui的经济如何不断发展。 是什么让您选择将自己的经济学背景应用于区块链和Web3领域&#xff1f; 起初&…

微信个人小程序申请 (AppID 和 AppSecret)

1. 登录微信公众平台 https://mp.weixin.qq.com/cgi-bin/loginpage?url%2Fcgi-bin%2Fhome%3Ft%3Dhome%2Findex%26lang%3Dzh_CN%26token%3D47421820 2. 右上角立即注册 3. 注册类型选择小程序 4. 账号信息 5. 邮箱激活 6. 小程序发布流程 7. 小程序信息 (前往填写) 8. 获取小程…

【一】初步认识数据库

数据库概览数据库 缘起表(Table)的理解用表来定义数据库数据库系统的理解概念层次的理解实例层次的理解 数据库管理系统的理解从用户角度看从系统实现角度看典型的数据库管理系统 数据库语言数据库定义、操纵、控制语言数据库语言 VS 高级语言 内容回顾练习 数据库概览 走马观…

QT笔记——QT自定义事件

我们有时候想发送自定义事件 1&#xff1a;创建自定义事件&#xff0c;首先我们需要知道它的条件 1&#xff1a;自定义事件需要继承QEvent 2&#xff1a;事件的类型需要在 QEvent::User 和 QEvent::MaxUser 范围之间&#xff0c;在QEvent::User之前 是预留给系统的事件 3&#…

前端先行模拟接口(mock+expres+json)

目录 mock模拟数据&#xff1a;data/static.js 路由&#xff1a;index.js 服务器&#xff1a;server.js yarn /node 启动服务器&#xff1a;yarn start 客户端&#xff1a;修改代理路径(修改设置后都要重启才生效) 示例 后端框架express构建服务器 前端发起请求 静态数…

smtplib.SMTPHeloError: (500, b‘Error: bad syntax‘)

如果你编写邮件收发工具的时候,有可能会遇到这个问题。这里直接给出解决办法。 目录 1、检查系统版本 2、点击右侧的更改适配器选项

0基础学C#笔记08:插入排序法

文章目录 前言一、过程简单描述&#xff1a;二、代码总结 前言 我们在玩打牌的时候&#xff0c;你是怎么整理那些牌的呢&#xff1f;一种简单的方法就是一张一张的来&#xff0c;将每一张牌插入到其他已经有序的牌中的适当位置。当我们给无序数组做排序的时候&#xff0c;为了…

十九、docker学习-Dockerfile

Dockerfile 官网地址 https://docs.docker.com/engine/reference/builder/Dockerfile其实就是我们用来构建Docker镜像的源码&#xff0c;当然这不是所谓的编程源码&#xff0c;而是一些命令的集合&#xff0c;只要理解它的逻辑和语法格式&#xff0c;就可以很容易的编写Docke…