【问题标题】:Why does JProfiler not show my classes/methods in maven tests profiling?为什么 JProfiler 不在 Maven 测试分析中显示我的类/方法?
【发布时间】:2014-06-18 10:19:25
【问题描述】:

我在我的 Maven 构建中运行了很长时间的测试。这些测试是使用failsafe plugin (mvn verify) 运行的集成测试。

我尝试使用 JProfiler 分析这些测试。

测试运行正常,但我在 JProfiler 中看不到任何有用的东西,好像 JProfiler 正在过滤掉它们。

我使用 openSUSE 13.1 x64,使用 Maven 3.2.1JProfiler 8.0.5

JProfiler 会话设置是默认设置,但有两个修改:

  • 在启动时自动启动 CPU 分析
  • 在执行完成后保持 VM 处于活动状态(以启用回溯信息)

我使用此命令启动配置文件构建:

MAVEN_OPTS="-agentpath:/opt/jprofiler8/bin/linux-x64/libjprofilerti.so=port=8849" mvn verify

Maven 和 JProfiler 在同一台机器上运行(本地分析)。

构建正常启动:

$ MAVEN_OPTS="-agentpath:/opt/jprofiler8/bin/linux-x64/libjprofilerti.so=port=8849" mvn verify
JProfiler> Protocol version 39
JProfiler> Using JVMTI
JProfiler> JVMTI version 1.1 detected.
JProfiler> 64-bit library
JProfiler> Listening on port: 8849.
JProfiler> Instrumenting native methods.
JProfiler> Can retransform classes.
JProfiler> Can retransform any class.
JProfiler> Native library initialized
JProfiler> VM initialized
JProfiler> Waiting for a connection from the JProfiler GUI ...
JProfiler> Using dynamic instrumentation
JProfiler> Time measurement: elapsed time
JProfiler> CPU profiling enabled
[INFO] Scanning for projects...
[INFO] 
[INFO] Using the builder org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder with a thread count of 1
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building...
[...]

也正常结束:

[...]
Results :

Tests run: 2766, Failures: 0, Errors: 0, Skipped: 0

[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 19:31 min
[INFO] Finished at: 2014-06-18T11:38:49+01:00
[INFO] Final Memory: 21M/107M
[INFO] ------------------------------------------------------------------------
JProfiler> Keeping VM alive until frontend disconnects.

JProfiler Hot Spots CPU view 告诉我这个:

对我来说,它是无用的东西,只有 maven 相关的方法(压缩,类加载)。

当我尝试通过(打开热点回溯)时,我没有找到与我运行的测试相关的任何内容。

此外,与实际总时间 (~19 mins 30s) 相比,测量的经过时间(如果我添加前 10 个热点固有时间)在很大程度上是微不足道的 (~10s)。

编辑:

起初,我使用我的 IDE (IntelliJ IDEA) 和 JProfiler 插件运行测试分析,但由于奇怪的行为我停止了。 似乎测试一直在运行而没有做任何事情。 我认为这是来自 IDE(或插件),因为测试通过 maven 运行良好。

编辑 2:

感谢@IngoKegel 的建议,如果我选择“所有州”,我会获得更多信息:

我看到了另外 4 个热点。但是,他们仍然没有给我有用的信息:

  1. 是对 j.u.c.ThreadPoolExecutor$Worker.run 的“过滤/直接调用”
  2. 是从 Maven(丛)到 j.l.r.Method.invoke 的单个调用(+ 无关紧要的调用)
  3. 和 4. 是“过滤/直接调用”到 o.a.maven.p.surefire.booterclient.o.ThreadStreamConsumer$Pumper.run

经过的时间好多了,但我仍然没有看到任何来自“我的”课程的东西。

为什么我的课程仍然被过滤?有没有办法看到它们?

此外,我不完全理解为什么在选择“可运行”状态时这些热点不显示。而且它是默认选项...

令人惊讶的是,如果我添加这前 4 个经过时间,它会给我~1h,但执行是~19min 20s,好像一些热点重叠。我认为这是“所有状态”选项的副作用。

【问题讨论】:

  • 你有没有试过把右上角的线程状态选择器设置为“所有状态”?
  • @IngoKegel,谢谢你的建议,我试过了,请看看我的EDIT 2:
  • 目前,我唯一可行的选择是使用 JUnit(不带 Maven)单独运行测试,使用以下命令:java -agentpath:... -cp ... org .junit.runner.JUnitCore ,这样我可以在 JProfiler 中看到有用的信息,但有很多缺点(需要单独运行每个测试,不能有全局指标,不切实际的命令行...)
  • 您会看到所有线程中经过时间的总和,因此如果您有多个线程,它总是超过挂钟时间。你的过滤器设置是什么?您应该为顶级包定义包容性过滤器。
  • 我找到了,这是一个 Maven 技巧:maven 中的集成测试在单独的 VM 中运行。并且 MAVEN_OPTS 在此 VM 中被忽略。解决方案是将故障安全插件配置为使用“jprofiler 选项”。通过正确的设置,我在分析中看到了有用的结果。我会为我的问题写一个清晰的答案来解释这一点。

标签: java maven jprofiler


【解决方案1】:

诀窍在于 Maven failsafe plugin单独的 JVM 中运行集成测试:

带有单元测试和集成测试的典型 Maven 构建可以轻松使用 3 个不同的 JVM:

  • Maven 主 JVM(compilepackage),由mvn 命令启动
    • Surefire JVM(单元测试),由 Maven 主 JVM 启动
    • 故障安全 JVM(集成测试),由 Maven 主 JVM 启动

分析 Maven 主 JVM 永远不会显示有关 Failsafe JVM 内完成的工作的信息。 此外,在 MAVEN_OPTS 中指定的选项仅传递给 Maven 主 JVM。

要分析其他 JVM 之一,您必须使用 pom.xml 文件中的插件配置单独配置它。

要回答这个问题,它需要以下插件配置:

<plugins>
    [...]
    <plugin>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>2.17</version>
        <executions>
            <execution>
                <goals>
                    <goal>integration-test</goal>
                    <goal>verify</goal>
                    <!-- to exclude IT from main build, comment the 'verify' goal -->
                </goals>
            </execution>
        </executions>
        <configuration>
            <argLine>${failsafeArgLine}</argLine>
        </configuration>
    </plugin>
    [...]
</plugin>

这里重要的部分是&lt;argLine&gt;${failsafeArgLine}&lt;/argLine&gt;

然后,可以通过failsafeArgLine 参数指定 JProfiler 代理选项:

mvn verify -DfailsafeArgLine="-agentpath:/opt/jprofiler8/bin/linux-x64/libjprofilerti.so=port=8849"

运行此命令将正常启动 Maven 构建(无需分析),然后在集成测试阶段开始时,它会要求 JProfiler 连接:

[...]
[INFO] 
[INFO] --- maven-failsafe-plugin:2.17:integration-test (default) @ project ---
[INFO] Failsafe report directory: /home/user/Repositories/project/target/failsafe-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
JProfiler> Protocol version 39
JProfiler> Using JVMTI
JProfiler> JVMTI version 1.1 detected.
JProfiler> 64-bit library
JProfiler> Listening on port: 8849.
JProfiler> Instrumenting native methods.
JProfiler> Can retransform classes.
JProfiler> Can retransform any class.
JProfiler> Native library initialized
JProfiler> VM initialized
JProfiler> Waiting for a connection from the JProfiler GUI ...
JProfiler> Using dynamic instrumentation
JProfiler> Time measurement: elapsed time
JProfiler> CPU profiling enabled
[...]

故障安全 VM 参数也可以直接在 pom.xml 文件中指定(而不是使用 failsafeArgLine 属性),但我更喜欢这样使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-07
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多