电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

淺談Java基準(zhǔn)性能測試之JMH

瀏覽:138日期:2022-08-09 15:24:45
目錄一、JMH vs JMeter二、JMH基本用法2.1、創(chuàng)建JMH項(xiàng)目2.2、編寫基準(zhǔn)測試代碼2.3、JMH打包、運(yùn)行2.4、JMH與Springboot三、JMH注解3.1、JMH Benchmark Modes3.2、Benchmark Time Units3.3、Benchmark State3.4、State Object @Setup @TearDown3.5、Fork3.6、Thread3.7、Warmup3.8、Measurement四、輸出測試結(jié)果一、JMH vs JMeter

JMeter可能是最常用的性能測試工具。它既支持圖形界面,也支持命令行,屬于黑盒測試的范疇,對非開發(fā)人員比較友好,上手也非常容易。圖形界面一般用于編寫、調(diào)試測試用例,而實(shí)際的性能測試建議還是在命令行下運(yùn)行。

很多場景下JMeter和JMH都可以做性能測試,但是對于嚴(yán)格意義上的基準(zhǔn)測試來說,只有JMH才適合。JMeter的測試結(jié)果精度相對JVM較低、所以JMeter不適合于類級別的基準(zhǔn)測試,更適合于對精度要求不高、耗時(shí)相對較長的操作。

JMeter測試精度差: JMeter自身框架比較重,舉個(gè)例子:使用JMH測試一個(gè)方法,平均耗時(shí)0.01ms,而使用JMeter測試的結(jié)果平均耗時(shí)20ms,相差200倍。JMeter內(nèi)置很多采樣器:JMeter內(nèi)置了支持多種網(wǎng)絡(luò)協(xié)議的采樣器,可以在不寫Java代碼的情況下實(shí)現(xiàn)很多復(fù)雜的測試。JMeter支持集群的方式運(yùn)行,方便模擬多用戶、高并發(fā)壓力測試。

總結(jié): JMeter適合一些相對耗時(shí)的集成功能測試,如API接口的測試。JMH適合于類或者方法的單元測試。

二、JMH基本用法2.1、創(chuàng)建JMH項(xiàng)目

官方推薦為JMH基準(zhǔn)測試創(chuàng)建單獨(dú)的項(xiàng)目,最簡單的創(chuàng)建JMH項(xiàng)目的方法就是基于maven項(xiàng)目原型的方式創(chuàng)建(如果是在windows環(huán)境下,需要對org.open.jdk.jmh這樣帶.的用雙引號包裹)。

mvn archetype:generate

          -DinteractiveMode=false

          -DarchetypeGroupId=org.openjdk.jmh

          -DarchetypeArtifactId=jmh-java-benchmark-archetype

          -DarchetypeVersion=1.21

          -DgroupId=com.jenkov

          -DartifactId=first-benchmark

          -Dversion=1.0

可以看到生成的項(xiàng)目pom文件中主要是添加了兩個(gè)jmh的依賴和設(shè)置了maven-shade-plugin的編譯方式(負(fù)責(zé)把項(xiàng)目的所有依賴jar包打入到目標(biāo)jar包中,與springboot的實(shí)現(xiàn)方式類似)。

<dependencies><dependency> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-core</artifactId> <version>${jmh.version}</version></dependency><dependency> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-generator-annprocess</artifactId> <version>${jmh.version}</version> <scope>provided</scope></dependency> </dependencies>...<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.2</version> <executions><execution> <phase>package</phase> <goals><goal>shade</goal> </goals> <configuration><finalName>${uberjar.name}</finalName><transformers> <transformer implementation='org.apache.maven.plugins.shade.resource.ManifestResourceTransformer'><mainClass>org.openjdk.jmh.Main</mainClass> </transformer></transformers><filters> <filter><!-- Shading signed JARs will fail without this. http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar--><artifact>*:*</artifact><excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude></excludes> </filter></filters> </configuration></execution> </executions></plugin>

生成的項(xiàng)目中已經(jīng)包含了一個(gè)class文件MyBenchmark.java,如下:

public class MyBenchmark { @Benchmark public void testMethod() {// This is a demo/sample template for building your JMH benchmarks. Edit as needed.// Put your benchmark code here. }}2.2、編寫基準(zhǔn)測試代碼

在上面生成的MyBenchmark類的testMethod中就可以添加基準(zhǔn)測試的java代碼,舉例如下:測試AtomicInteger的incrementAndGet的基準(zhǔn)性能。

public class MyBenchmark { static AtomicInteger integer = new AtomicInteger(); @Benchmark public void testMethod() {// This is a demo/sample template for building your JMH benchmarks. Edit as needed.// Put your benchmark code here.integer.incrementAndGet(); }}2.3、JMH打包、運(yùn)行

項(xiàng)目打包

mvn clean install

運(yùn)行生成的目標(biāo)jar包benchmark.jar:

java -jar benchmark.jar

# JMH version: 1.21

# VM version: JDK 1.8.0_181, Java HotSpot(TM) 64-Bit Server VM, 25.181-b13

# VM invoker: C:Javajdk1.8.0_181jrebinjava.exe

# VM options: <none>

# Warmup: 5 iterations, 10 s each

# Measurement: 5 iterations, 10 s each

# Timeout: 10 min per iteration

# Threads: 1 thread, will synchronize iterations

# Benchmark mode: Throughput, ops/time

# Benchmark: org.sample.MyBenchmark.testMethod

# Run progress: 0.00% complete, ETA 00:01:40

# Fork: 1 of 1

# Warmup Iteration   1: 81052462.185 ops/s

# Warmup Iteration   2: 80152956.333 ops/s

# Warmup Iteration   3: 81305026.522 ops/s

# Warmup Iteration   4: 81740215.227 ops/s

# Warmup Iteration   5: 82398485.097 ops/s

Iteration   1: 82176523.804 ops/s

Iteration   2: 81818881.730 ops/s

Iteration   3: 82812749.807 ops/s

Iteration   4: 82406672.531 ops/s

Iteration   5: 74270344.512 ops/s

Result 'org.sample.MyBenchmark.testMethod':

  80697034.477 ±(99.9%) 13903555.960 ops/s [Average]

  (min, avg, max) = (74270344.512, 80697034.477, 82812749.807), stdev = 3610709.330

  CI (99.9%): [66793478.517, 94600590.437] (assumes normal distribution)

# Run complete. Total time: 00:01:41

REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on

why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial

experiments, perform baseline and negative tests that provide experimental control, make sure

the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.

Do not assume the numbers tell you what you want them to tell.

Benchmark                Mode  Cnt         Score          Error  Units

MyBenchmark.testMethod  thrpt    5  80697034.477 ± 13903555.960  ops/s

從上面的日志我們大致可以了解到 JMH的基準(zhǔn)測試主要經(jīng)歷了下面幾個(gè)過程:

1.打印本次測試的配置,warmup:5輪;measurement:5輪;每輪:10s;啟動1個(gè)線程做測試;基準(zhǔn)測試指標(biāo):吞吐量(throughput,單位是s);測試方法MyBenchmark.testMethod

2.啟動一個(gè)JVM進(jìn)程做基準(zhǔn)測試(也可以設(shè)置啟動多個(gè)進(jìn)程,減少隨機(jī)因素的誤差影響)

3.在JVM進(jìn)程中先執(zhí)行了5輪的預(yù)熱(warmup),每輪10s,總共50s的預(yù)熱時(shí)間。預(yù)熱的數(shù)據(jù)不作為基準(zhǔn)測試的參考。

4.測試了5輪,每輪10s,總共50s的測試時(shí)間

5.匯總測試數(shù)據(jù)、生成結(jié)果報(bào)表。最終結(jié)論是吞吐量(80697034.477 ±13903555.960 ops/s),其中80697034.477 是結(jié)果,13903555.960是誤差范圍。

2.4、JMH與Springboot

在對Springboot項(xiàng)目做JMH基準(zhǔn)測試時(shí)可能會因?yàn)閙aven-shade-plugin插件的問題打包報(bào)錯(cuò),需要在JMH的maven-shade-plugin的插件配置中添加id即可。項(xiàng)目的pom可能如下:

<project xmlns='http://maven.apache.org/POM/4.0.0' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd'> <modelVersion>4.0.0</modelVersion> <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.7.RELEASE</version><relativePath/> </parent>...<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.2</version> <executions><execution> <!-- 需要在此處添加一個(gè)id標(biāo)簽,否則mvn package時(shí)會報(bào)錯(cuò) --> <id>shade-all-dependency-jar</id> <phase>package</phase> <goals><goal>shade</goal> </goals> <configuration>... </configuration></execution> </executions></plugin>...</project>

在測試代碼中正常基于SpringBootApplication構(gòu)建ConfigurableApplicationContext從而獲取bean的方式獲取對象測試即可。

public class StringRedisTemplateBenchmark { StringRedisTemplate redisTemplate;@Setup(Level.Trial) public void setUp() {redisTemplate = SpringApplication.run(SpringBootApplicationClass.class).getBean(StringRedisTemplate.class); }@Benchmark public void testGet() {redisTemplate.opsForValue().get('testkey'); }}@SpringBootApplicationpublic class SpringBootApplicationClass {}

application.properties

lettuce.pool.maxTotal=50lettuce.pool.maxIdle=10lettuce.pool.minIdle=0lettuce.sentinel.master=mymasterlettuce.sentinel.nodes=10.xx.xx.xx:26379,10.xx.xx.xx:26379lettuce.password=xxxxxx三、JMH注解

JMH測試的相關(guān)配置大多是通過注解的方式體現(xiàn)的。

具體每個(gè)注解的使用實(shí)例也可以參考官網(wǎng)

http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/

3.1、JMH Benchmark Modes

JMH benchmark支持如下幾種測試模式:

Throughput: 吞吐量,測試每秒可以執(zhí)行操作的次數(shù) Average Time: 平均耗時(shí),測試單次操作的平均耗時(shí) Sample Time:采樣耗時(shí),測試單次操作的耗時(shí),包括最大、最小耗時(shí),已經(jīng)百分位耗時(shí)等 Single Shot Time: 只計(jì)算一次的耗時(shí),一般用來測試?yán)鋯拥男阅埽ú辉O(shè)置JVM預(yù)熱) All: 測試上面的所有指標(biāo)

默認(rèn)的benchmark mode是Throughput,可以通過注解的方式設(shè)置BenchmarkMode,注解支持放在類或方法上。如下所示設(shè)置了Throughput和SampleTime兩個(gè)Benchmark mode。

@BenchmarkMode({Mode.Throughput, Mode.SampleTime})public class MyBenchmark { static AtomicInteger integer = new AtomicInteger(); @Benchmark public void testMethod() {// This is a demo/sample template for building your JMH benchmarks. Edit as needed.// Put your benchmark code here.integer.incrementAndGet(); }}3.2、Benchmark Time Units

JMH支持設(shè)置打印基準(zhǔn)測試結(jié)果的時(shí)間單位,通過@OutputTimeUnit注解的方式設(shè)置。

@OutputTimeUnit(TimeUnit.SECONDS)public class MyBenchmark { static AtomicInteger integer = new AtomicInteger(); @Benchmark public void testMethod() {integer.incrementAndGet(); }}3.3、Benchmark State

有時(shí)候我們在做基準(zhǔn)測試的時(shí)候會需要使用一些變量、字段,@State注解是用來配置這些變量的生命周期,@State注解可以放在類上,然后在基準(zhǔn)測試方法中可以通過參數(shù)的方式把該類對象作為參數(shù)使用。@State支持的生命周期類型:

Benchmark: 整個(gè)基準(zhǔn)測試的生命周期,多個(gè)線程共用同一份實(shí)例對象。該類內(nèi)部的@Setup @TearDown注解的方法可能會被任一個(gè)線程執(zhí)行,但是只會執(zhí)行一次。 Group: 每一個(gè)Group內(nèi)部共享同一個(gè)實(shí)例,需要配合@Group @GroupThread使用。該類內(nèi)部的@Setup @TearDown注解的方法可能會該Group內(nèi)的任一個(gè)線程執(zhí)行,但是只會執(zhí)行一次。 Thread:每個(gè)線程的實(shí)例都是不同的、唯一的。該類內(nèi)部的@Setup @TearDown注解的方法只會被當(dāng)前線程執(zhí)行,而且只會執(zhí)行一次。

被@State標(biāo)示的類必須滿足如下兩個(gè)要求:

類必須是public的

必須有無參構(gòu)造函數(shù)

3.4、State Object @Setup @TearDown

在@Scope注解標(biāo)示的類的方法上可以添加@Setup和@TearDwon注解。@Setup:用來標(biāo)示在Benchmark方法使用State對象之前需要執(zhí)行的操作。@TearDown:用來標(biāo)示在Benchmark方法之后需要對State對象執(zhí)行的操作。如下示例:

@OutputTimeUnit(TimeUnit.SECONDS)public class MyBenchmark {@Benchmark public void testMethod(TestAddAndGetState state) {state.getInteger().incrementAndGet(); } @State(Scope.Benchmark) public static class TestAddAndGetState {private AtomicInteger integer;@Setup(Level.Iteration)public void setup() { integer = new AtomicInteger();}public AtomicInteger getInteger() { return integer;} }}

@Setup、@TearDown支持設(shè)置Level級別,Level有三個(gè)值:

Trial: 每次benchmark前/后執(zhí)行一次,每次benchmark會包含多輪(Iteration) Iteration: 每輪執(zhí)行前/后執(zhí)行一次 Invocation: 每次調(diào)用測試的方法前/后都執(zhí)行一次,這個(gè)執(zhí)行頻率會很高,一般用不上。3.5、Fork

@Fork注解用來設(shè)置啟動的JVM進(jìn)程數(shù)量,多個(gè)進(jìn)程是串行的方式啟動的,多個(gè)進(jìn)程可以減少偶發(fā)因素對測試結(jié)果的影響。

3.6、Thread

@Thread用來配置執(zhí)行測試啟動的線程數(shù)量

3.7、Warmup

@Warmup 用來配置預(yù)熱的時(shí)間,如下所示配置預(yù)熱五輪,每輪1second,也就是說總共會預(yù)熱5s左右,在這5s內(nèi)會不停的循環(huán)調(diào)用測試方法,但是預(yù)熱時(shí)的數(shù)據(jù)不作為測試結(jié)果參考。

@Warmup(iterations = 5, time = 1)3.8、Measurement

@Measurement用來配置基準(zhǔn)測試的時(shí)間,如下所示配置預(yù)熱10輪,每輪1second,也就是說總共會測試10s左右,在這10s內(nèi)會不停的循環(huán)調(diào)用測試方法,同事測試數(shù)據(jù)會被基準(zhǔn)測試結(jié)果參考。

@Measurement(iterations = 5, time = 1)四、輸出測試結(jié)果

jmh支持多種格式的結(jié)果輸出text, csv, scsv, json, latex

如下打印出json格式的:

java -jar benchmark.jar -rf json

以上就是淺談Java基準(zhǔn)性能測試之JMH的詳細(xì)內(nèi)容,更多關(guān)于Java基準(zhǔn)性能測試 JMH的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 解放卡车|出口|济南重汽|报价大全|山东三维商贸有限公司 | 上海深蓝_缠绕机_缠膜机-上海深蓝机械装备有限公司 | 铁素体测量仪/检测仪/铁素体含量测试仪-苏州圣光仪器有限公司 | 谈股票-今日股票行情走势分析-牛股推荐排行榜 | 济南保安公司加盟挂靠-亮剑国际安保服务集团总部-山东保安公司|济南保安培训学校 | 不锈钢搅拌罐_高速搅拌罐厂家-无锡市凡格德化工装备科技有限公司 | 点胶机_点胶阀_自动点胶机_智能点胶机_喷胶机_点胶机厂家【欧力克斯】 | 桐城新闻网—桐城市融媒体中心主办 | 低温等离子清洗机(双气路进口)-嘉润万丰 | 铝镁锰板_铝镁锰合金板_铝镁锰板厂家_铝镁锰金属屋面板_安徽建科 | 精密交叉滚子轴承厂家,转盘轴承,YRT转台轴承-洛阳千协轴承 | 全球化工设备网—化工设备,化工机械,制药设备,环保设备的专业网络市场。 | 铝镁锰板_铝镁锰合金板_铝镁锰板厂家_铝镁锰金属屋面板_安徽建科 | 巨野月嫂-家政公司-巨野县红墙安康母婴护理中心 | 招商帮-一站式网络营销服务|搜索营销推广|信息流推广|短视视频营销推广|互联网整合营销|网络推广代运营|招商帮企业招商好帮手 | 烽火安全网_加密软件、神盾软件官网| 吉祥新世纪铝塑板_生产铝塑板厂家_铝塑板生产厂家_临沂市兴达铝塑装饰材料有限公司 | 北京易通慧公司从事北京网站优化,北京网络推广、网站建设一站式服务商-北京网站优化公司 | 软瓷_柔性面砖_软瓷砖_柔性石材_MCM软瓷厂家_湖北博悦佳软瓷 | 无尘烘箱_洁净烤箱_真空无氧烤箱_半导体烤箱_电子防潮柜-深圳市怡和兴机电 | 耐磨陶瓷管道_除渣器厂家-淄博浩瀚陶瓷科技有限公司 | 杭州中央空调维修_冷却塔/新风机柜/热水器/锅炉除垢清洗_除垢剂_风机盘管_冷凝器清洗-杭州亿诺能源有限公司 | 酒吧霸屏软件_酒吧霸屏系统,酒吧微上墙,夜场霸屏软件,酒吧点歌软件,酒吧互动游戏,酒吧大屏幕软件系统下载 | 污水/卧式/潜水/钻井/矿用/大型/小型/泥浆泵,价格,参数,型号,厂家 - 安平县鼎千泵业制造厂 | 酒店品牌设计-酒店vi设计-酒店标识设计【国际级】VI策划公司 | SF6环境监测系统-接地环流在线监测装置-瑟恩实业 | 水质监测站_水质在线分析仪_水质自动监测系统_多参数水质在线监测仪_水质传感器-山东万象环境科技有限公司 | 产业规划_产业园区规划-产业投资选址及规划招商托管一体化服务商-中机院产业园区规划网 | 京马网,京马建站,网站定制,营销型网站建设,东莞建站,东莞网站建设-首页-京马网 | 混合气体腐蚀试验箱_盐雾/硫化氢/气体腐蚀试验箱厂家-北京中科博达 | 振动筛,震动筛,圆形振动筛,振动筛价格,振动筛厂家-新乡巨宝机电 蒸汽热收缩机_蒸汽发生器_塑封机_包膜机_封切收缩机_热收缩包装机_真空机_全自动打包机_捆扎机_封箱机-东莞市中堡智能科技有限公司 | 高低温试验房-深圳高低温湿热箱-小型高低温冲击试验箱-爱佩试验设备 | 塑胶跑道_学校塑胶跑道_塑胶球场_运动场材料厂家_中国塑胶跑道十大生产厂家_混合型塑胶跑道_透气型塑胶跑道-广东绿晨体育设施有限公司 | 逗网红-抖音网红-快手网红-各大平台网红物品导航 | SMN-1/SMN-A ABB抽屉开关柜触头夹紧力检测仪-SMN-B/SMN-C-上海徐吉 | 薄壁轴承-等截面薄壁轴承生产厂家-洛阳薄壁精密轴承有限公司 | 盘古网络技术有限公司| 手持式线材张力计-套帽式风量罩-深圳市欧亚精密仪器有限公司 | 山楂片_雪花_迷你山楂片_山楂条饼厂家-青州市丰源食品厂 | 硫化罐_蒸汽硫化罐_大型硫化罐-山东鑫泰鑫智能装备有限公司 | 面粉仓_储酒罐_不锈钢储酒罐厂家-泰安鑫佳机械制造有限公司 |