JMH:如何使用分叉、线程和调试

9

我最近开始使用JMH,并想知道是否有可能对其进行调试。

首先,我尝试像调试其他程序一样进行调试,但它抛出了“未初始化传输”,所以我无法以老式方式进行调试。

接下来,我尝试在互联网上搜索,并找到了有人说需要将forks设置为0才行,然后我尝试了一下,结果可行。

不幸的是,我仍然不太明白为什么fork会影响调试,或者fork如何影响我在JMH中看到的内容。 我目前所知道的只是,当您在OptionBuilder上放置.forks(number)时,它说明基准测试将在多少个进程上运行。 但是,如果我放置.forks(3),它会异步地在3个进程上运行每个@Benchmark方法吗?

关于.forks(number),.threads(number)如何改变基准测试的运行方式以及它们如何影响调试的解释将真正澄清问题。

2个回答

10

普通的 JMH 运行在任何给定时间都有两个进程运行。第一个("host")进程处理运行。第二个("forked")进程是运行给定基准测试的一个试验的进程-实现隔离。通过注释或命令行请求 N 个分支(命令行优先于注释)会为 forked 进程连续调用 N 次。请求零个分支将直接在 host 进程本身中运行工作负载。

因此,有两件事情需要进行调试:

a) 通常,可以附加到 forked 进程并在其中进行调试。将工作负载配置为运行更长时间,以便有足够的时间进行附加和查看。forked 进程通常具有 "ForkedMain" 作为其入口点,在 "jps" 中可见。

b) 如果上面的方法不起作用,请使用 -f 0 并附加到主机进程本身。


1
这真是个让人头疼的问题,要让它工作起来(现在我写下这句话,感觉它很琐碎)。
首先,我试图使用gradle调试DTraceAsmProfiler(类似于Mac上的perfasm)。
首先,我有一个名为“jmh”的gradle任务,看起来像这样:
task jmh(type: JavaExec, dependsOn: jmhClasses) {
    // the actual class to run
    main = 'com.eugene.AdditionPollution'
    classpath = sourceSets.jmh.compileClasspath + sourceSets.jmh.runtimeClasspath

    // I build JMH from sources, thus need this
    repositories {
        mavenLocal()
        maven {
            url '/Users/eugene/.m2/repository'
        }
    }
}

然后我需要在 Intellij 中创建一个调试配置(没有什么不寻常的):

enter image description here

然后简单地运行:
sudo gradle -Dorg.gradle.debug=true jmh --debug-jvm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接