首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用javaagent进行JMH测试

用javaagent进行JMH测试
EN

Stack Overflow用户
提问于 2014-08-15 14:45:47
回答 2查看 1.3K关注 0票数 3

我正在尝试度量JVM代理对性能的影响,以确保它不会使我们试图运行的测试失效(也许可以从prod中提取一些样本)。这种情况是一组BTrace脚本,它们将在自动负载测试期间运行,但是这个问题可能对任何代理都是通用的。

为了运行这些基准测试,我设置了一个小型JMH项目,并将代理附加为:

代码语言:javascript
复制
java -javaagent:/home/ssube/btrace/build/btrace-agent.jar=scriptdir=/home/ssube/btrace/scripts/,port=0 -jar benchmarks.jar

这样做会导致每次JVM被JMH分叉时出现以下错误:

代码语言:javascript
复制
# Run progress: 0.00% complete, ETA 00:02:00
# Fork: 1 of 1
Exception in thread "main" java.lang.IllegalArgumentException: org.openjdk.jmh.runner.options.CommandLineOptions; local class incompatible: stream classdesc serialVersionUID = 8906142321598115825, local class serialVersionUID = 7529911323947566771
    at org.openjdk.jmh.runner.ForkedMain.main(ForkedMain.java:72)
<binary link had failed, forked VM corrupted the stream? Use EXTRA verbose to print exception>
<forked VM failed with exit code 1>
<stdout last='10 lines'>
</stdout>
<stderr last='10 lines'>
Exception in thread "main" java.lang.IllegalArgumentException: org.openjdk.jmh.runner.options.CommandLineOptions; local class incompatible: stream classdesc serialVersionUID = 8906142321598115825, local class serialVersionUID = 7529911323947566771
    at org.openjdk.jmh.runner.ForkedMain.main(ForkedMain.java:72)
</stderr>

# VM invoker: /usr/java/jdk1.8.0_11/jre/bin/java
# VM options: -javaagent:/home/ssube/btrace/build/btrace-agent.jar=scriptdir=/home/ssube/btrace/scripts/,port=0
# Warmup: 20 iterations, 1 s each
# Measurement: 20 iterations, 1 s each
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.stackoverflow.questions.ShaderBench.testProcessProc

我的类没有一个是可序列化的,也没有一个serialVersionUID。JMH基准测试在不附加BTrace代理的情况下工作,代理和脚本在没有JMH的代码上工作。

(如何)可以将javaagent附加到一组JMH基准测试并捕获代理造成的性能差异?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-16 11:01:52

这里是JMH的维护者。从维护人员的角度来看,这就像是JMH的错误,因为它没有为自己的内部类提供SUIDs,所以它可以抵抗良性的检测。现在用3d44d68e45be解决了这个问题

代码语言:javascript
复制
changeset:   960:3d44d68e45be
tag:         tip
user:        shade
date:        Sat Aug 16 15:00:18 2014 +0400
summary:     Apply SUIDs for all Serializable classes: this protects from the benign instrumentation.

请尝试使用出血缘JMH,看看它是否解决了您的问题。请注意,提供SUIDs并不能保护我们不受Java代理可以进行的序列化形式的明显更改(例如,注入非瞬态字段),因此,如果BTrace是(Mis)那样的行为,我们就有麻烦了。

如果上面的JMH更改不起作用,请向jmh-dev邮件列表发送一些最低限度的可再现场景,我们将看到可以做些什么来缓解这个问题。

否则,请将org.openjdk.jmh.*类排除在工具中。

票数 6
EN

Stack Overflow用户

发布于 2014-08-15 15:14:33

我最近也遇到了同样的问题。我假设它与JMH叉子有关。由于您可以从基准测试的输出中读取,JMH创建了一个分叉1 of 1,其中JMH为每个测试行启动一个新的JVM实例。这些JVM不再连接您的代理。

这会影响使用代理重新定义的类,这些类是在分叉JVM上加载的,没有代理。因此,您将得到序列化问题。由于您没有为类定义显式UID,因此这些UID是隐式计算的。因此,分叉JVM将认识到,原始JVM的类与分叉JVM的类不同,导致错误的原因是什么。您可以通过显式定义UID来避免这些序列化问题,但是您的类仍然不会被检测。

相反,尝试用@Fork(0)注释基准测试,这完全禁用了分叉。不过,如果这对你的结果造成了太大的扭曲,你应该小心。当您的代码可以通过概要分析进行大量优化时,情况就是如此。尤其是当您在基准测试之间共享代码时,来自第一个基准测试的概要文件将影响您的其他基准测试,通常情况会变得更糟。

另一个解决方案是也将代理应用于分叉JVM。为此,@Fork注释提供了几个参数。对于您的例子,您可以定义:

代码语言:javascript
复制
@Fork(jvmArgs = "-javaagent:/home/ssube/btrace/build/btrace-agent.jar=scriptdir=/home/ssube/btrace/scripts/,port=0")

但是,请注意,这使得构建依赖于您的文件系统。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25328570

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档