JProfiler帮助文档

Gradle 任务

JProfiler 支持通过 Gradle 使用特殊任务进行分析。此外,JProfiler 还提供了许多 用于处理快照的命令行可执行文件, 这些文件都有对应的 Gradle 任务。

使用 Gradle 任务

要在 Gradle 构建文件中使用 JProfiler Gradle 任务,可以使用 plugins 块:

plugins {
    id 'com.jprofiler' version 'X.Y.Z'
}

如果不想为此使用 Gradle 插件仓库,Gradle 插件也可在文件 bin/gradle.jar 中找到。

接下来,需要告知 JProfiler Gradle 插件 JProfiler 的安装位置。

jprofiler {
    installDir = file('/path/to/jprofiler/home')
}

从 Gradle 进行分析

使用类型为 com.jprofiler.gradle.JavaProfile 的任务,可以分析任何 Java 进程。 该类继承自 Gradle 内置的 JavaExec,因此可以使用相同的参数来配置进程。 对于测试分析,请使用类型为 com.jprofiler.gradle.TestProfile 的任务, 它继承自 Gradle 的 Test 任务。

在没有任何额外配置的情况下,两个任务都会启动一个交互式分析会话(session), 分析代理(agent)在默认端口 8849 上等待来自 JProfiler GUI 的连接。 对于离线分析,可以引用导出的配置文件,或者直接使用下表中所示的属性配置常用 session 设置和自动化记录。

属性 描述 是否必填
offline 分析运行是否应处于离线模式。 否,offlinenowait 不能同时为 true
nowait 分析是否应立即开始,或者被分析的 JVM 是否应等待来自 JProfiler GUI 的连接。
sessionId 定义应从中获取配置文件设置(profiling settings)的 session ID。 如果 nowaitoffline 均未设置,则此项无效, 因为在这种情况下,分析 session 将在 GUI 中选择。 仅当为离线分析设置了 configFile
configFile 定义应从中读取配置文件设置(profiling settings)的配置文件。 如果在离线分析中省略此属性,可以直接使用下面的属性配置常用 session 设置。 如果这些属性均未设置,则使用默认的离线 session 设置。
callTreeMode 为无配置文件的离线分析选择调用树(call tree)收集模式。在 Gradle 中,可以使用 com.jprofiler.buildtools.CallTreeMode 的值。字符串值为 samplinginstrumentationinstrasync
profile, compact, ignore 用于无配置文件的离线分析的包或类过滤器。值可以是以 : 分隔条目的字符串, 或字符串列表。
lineNumbers 是否应在调用树(call tree)中记录行号。
snapshotFile 用于自动化离线记录的快照文件。如果设置了此项但未设置 recording, 则记录 CPU 数据。线程和遥测(telemetry)始终会被记录。
recording 用于自动化离线记录的数据类型。值可以是以 : 分隔条目的字符串, 或字符串列表。常用值有 cpuallocationjdbcjpamongo_dbhttp_serverhttp_client。 支持的记录值的完整列表记录在相应的 -agentpath 选项中。选择探针(probe)记录也会同时记录 CPU 数据。 否,但如果设置了此项则需要 snapshotFile
duration 自动化离线记录的持续时间,例如 30s10m1h。如果未设置此属性,记录将持续到 JVM 终止,届时保存快照。 否,但如果设置了此项则需要 snapshotFile
delay 自动化离线记录开始前的延迟时间,例如 10s1m 否,但如果设置了此项则需要 snapshotFile
port 定义分析代理(agent)应监听来自 JProfiler GUI 连接的端口号。 此端口必须与 remote session 配置中配置的端口相同。 如果未设置或为零,将使用默认端口(8849)。 如果设置了 offline,则此项无效,因为在这种情况下没有来自 GUI 的连接。
debugOptions 如果需要传递任何额外的库(library)参数用于调优或调试,可以通过此属性进行设置。

以下是一个分析包含 main 方法的 Java 类的示例,该类由所在项目编译:

task run(type: com.jprofiler.gradle.JavaProfile) {
    mainClass = 'com.mycorp.MyMainClass'
    classpath sourceSets.main.runtimeClasspath
    offline = true
    callTreeMode = 'sampling'
    profile = ['com.mycorp.', 'org.example.']
    snapshotFile = file('build/snapshots/run.jps')
    recording = ['cpu', 'allocation', 'jdbc']
    duration = '10m'
}

对于无配置文件属性未涵盖的高级设置,请导出配置文件并通过 configFilesessionId 引用它。

task run(type: com.jprofiler.gradle.JavaProfile) {
    mainClass = 'com.mycorp.MyMainClass'
    classpath sourceSets.main.runtimeClasspath
    offline = true
    sessionId = 80
    configFile = file('path/to/jprofiler_config.xml')
}

您可以在 api/samples/offline 示例项目中查看此任务的可运行示例。 与标准的 JavaExec 任务不同,JavaProfile 任务 也可以通过调用其上的 createProcess() 在后台启动。 请参阅 api/samples/mbean 示例项目以了解此功能的演示。

如果需要分析所需的 VM 参数,com.jprofiler.gradle.SetAgentpathProperty 任务 会将其分配给一个属性,该属性的名称通过 propertyName 属性配置。 应用 JProfiler 插件会自动向您的项目添加一个名为 setAgentPathProperty 的此类型任务。要获取前一个示例中将使用的 VM 参数,只需添加:

setAgentPathProperty {
    propertyName = 'profilingVmParameter'
    offline = true
    callTreeMode = 'sampling'
    profile = ['com.mycorp.', 'org.example.']
}

到您的项目中,并为某个其他任务添加对 setAgentPathProperty 的依赖。 然后,您可以在该任务的执行阶段使用项目属性 profilingVmParameter。 在将属性赋值给其他任务属性时,请用 doFirst {...} 代码块包围其用法, 以确保处于 Gradle 执行阶段而非配置阶段。

从快照导出数据

com.jprofiler.gradle.Export 任务可用于从已保存的快照中导出视图(view), 并复制 bin/jpexport 命令行工具 的参数。 它支持以下属性:

属性 描述 是否必填
snapshotFile 快照文件的路径。必须是扩展名为 .jps 的文件。
ignoreErrors 忽略无法为视图(view)设置选项时发生的错误,并继续处理下一个视图(view)。 默认值为 false,表示在发生第一个错误时终止导出。
csvSeparator CSV 导出的字段分隔符。默认为 ","。
obfuscator 对所选混淆器的类名和方法名进行反混淆。默认为 "none",对于其他值, 必须指定 mappingFile 选项。可选值为 noneproguardyguard
mappingFile 所选混淆器的映射文件。仅当指定了 obfuscator 属性时才可设置。 仅当指定了 obfuscator

在导出任务上,调用 views 方法并向其传递一个闭包,在闭包中一次或多次调用 view(name, file[, options])。每次调用 view 都会生成一个输出文件。 name 参数是视图(view)名称。有关可用视图(view)名称的列表,请参阅 jpexport 命令行可执行文件 的帮助页面。 file 参数是输出文件,可以是绝对路径文件或相对于项目的文件。 最后,可选的 options 参数是一个包含所选视图(view)导出选项的 map。

以下是使用导出任务的示例:

task export(type: com.jprofiler.gradle.Export) {
    snapshotFile = file('snapshot.jps')
    views {
        view('CallTree', 'callTree.html')
        view('HotSpots', 'hotSpots.html',
            [threadStatus: 'all', expandBacktraces: 'true'])
    }
}

比较快照

bin/jpcompare 命令行工具 类似, com.jprofiler.gradle.Compare 任务可以比较两个或多个快照。 其属性如下:

属性 描述 是否必填
snapshotFiles 要比较的快照文件。可以传递任何包含 Gradle 解析为文件集合的对象的 Iterable

如果快照文件具有各自的反混淆设置,文件名可以采用以下形式: <file name>:<obfuscator>:<mapping file>, 其中 <obfuscator> 和 <mapping file> 对应下面的全局选项。

obfuscator 对所选混淆器的类名和方法名进行反混淆。默认为 "none",对于其他值, 必须指定 mappingFile 选项。可选值为 noneproguardyguard
mappingFile 所选混淆器的映射文件。仅当指定了 obfuscator 属性时才可设置。 仅当指定了 obfuscator
sortByTime 如果设置为 true,所有提供的快照文件将按其文件修改时间排序, 否则将按照在 snapshotFiles 属性中指定的顺序进行比较。
ignoreErrors 忽略无法为比较设置选项时发生的错误,并继续进行下一次比较。 默认值为 false,表示在发生第一个错误时终止导出。

就像为 Export 任务定义导出视图(view)一样,Compare 任务 有一个 comparisons 方法,其中对 comparison(name, file[, options]) 的嵌套调用定义了要执行的比较。可用比较名称列表可在 jpcompare 命令行可执行文件 的帮助页面上找到。

以下是使用比较任务的示例:

task compare(type: com.jprofiler.gradle.Compare) {
    snapshotFiles = files('snapshot1.jps', 'snapshot2.jps')
    comparisons {
        comparison('CallTree', 'callTree.html')
        comparison('HotSpots', 'hotSpots.csv',
            [valueSummation: 'total', format: 'csv'])
    }
}

或者,如果要为多个快照创建遥测(telemetry)比较:

task compare(type: com.jprofiler.gradle.Compare) {
    snapshotFiles = fileTree(dir: 'snapshots', include: '*.jps')
    sortByTime = true
    comparisons {
        comparison('TelemetryHeap', 'heap.html', [valueType: 'maximum'])
        comparison('ProbeTelemetry', 'jdbc.html', [probeId: 'JdbcProbe'])
    }
}

分析堆快照

Gradle 任务 com.jprofiler.gradle.Analyze bin/jpanalyze 命令行工具 具有相同的功能。

该任务具有与 Compare 任务类似的 snapshotFiles 属性, 用于指定要处理的快照,以及与 Export 任务类似的 obfuscatormappingfile 属性用于反混淆。属性 removeUnreferencedretainSoftretainWeakretainPhantomretainFinalizerretained 对应命令行工具的参数。

以下是使用 Analyze 任务的示例:

task analyze(type: com.jprofiler.gradle.Analyze) {
    snapshotFiles = fileTree(dir: 'snapshots', include: '*.jps')
    retainWeak = true
    obfuscator = 'proguard'
    mappingFile = file('obfuscation.txt')
}