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 分析运行是否应处于离线模式。 否,offline 和 nowait 不能同时为 true。
nowait 分析是否应立即开始,或者被分析的 JVM 是否应等待来自 JProfiler GUI 的连接。
sessionId 定义应从中获取配置文件设置(profiling settings)的 session ID。 如果 nowait 和 offline 均未设置,则此项无效, 因为在这种情况下,分析 session 将在 GUI 中选择。 仅当为离线分析设置了 configFile 时
configFile 定义应从中读取配置文件设置(profiling settings)的配置文件。 如果在离线分析中省略此属性,可以直接使用下面的属性配置常用 session 设置。 如果这些属性均未设置,则使用默认的离线 session 设置。 否
callTreeMode 为无配置文件的离线分析选择调用树(call tree)收集模式。在 Gradle 中,可以使用 com.jprofiler.buildtools.CallTreeMode 的值。字符串值为 sampling、instrumentation、instr 和 async。 否
profile, compact, ignore 用于无配置文件的离线分析的包或类过滤器。值可以是以 : 分隔条目的字符串, 或字符串列表。 否
lineNumbers 是否应在调用树(call tree)中记录行号。 否
snapshotFile 用于自动化离线记录的快照文件。如果设置了此项但未设置 recording, 则记录 CPU 数据。线程和遥测(telemetry)始终会被记录。 否
recording 用于自动化离线记录的数据类型。值可以是以 : 分隔条目的字符串, 或字符串列表。常用值有 cpu、allocation、 jdbc、jpa、mongo_db、 http_server 和 http_client。 支持的记录值的完整列表记录在相应的 -agentpath 选项中。选择探针(probe)记录也会同时记录 CPU 数据。 否,但如果设置了此项则需要 snapshotFile
duration 自动化离线记录的持续时间,例如 30s、10m 或 1h。如果未设置此属性,记录将持续到 JVM 终止,届时保存快照。 否,但如果设置了此项则需要 snapshotFile
delay 自动化离线记录开始前的延迟时间,例如 10s 或 1m。 否,但如果设置了此项则需要 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'
}

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

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 选项。可选值为 none、 proguard 或 yguard。 否
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 选项。可选值为 none、 proguard 或 yguard。 否
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 任务类似的 obfuscator 和 mappingfile 属性用于反混淆。属性 removeUnreferenced、retainSoft、retainWeak、 retainPhantom、retainFinalizer 和 retained 对应命令行工具的参数。

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

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