Packages async-profiler releases in a JAR
with an AsyncProfilerLoader
(version 2+) that loads the suitable native library for the current platform.
This is usable as a java agent (same arguments as the async-profiler agent) and as the basis for other libraries. The real rationale behind this library is that the async-profiler is a nice tool, but it cannot be easily integrated into other Java-based tools.
The wrapper is tested against all relevant tests of the async-profiler tool, ensuring that it has the same behavior.
Take the all
build and you have a JAR that provides the important features of async-profiler on all supported
platforms.
A changelog can be found in the async-profiler repository, as this library should rarely change itself.
This project assumes that you used async-profiler before, if not, don't worry, you can still use this project, but be aware that its documentation refers you to the async-profiler documentation a lot.
fdtransfer is currently not supported, feel free to create an issue if you need it.
You can download the latest release from the latest release page. As a shortcut, the wrapper for all platforms can be found here.
It should be up-to-date with the latest async-profiler release, but if not, feel free to create an issue.
To use the library as a dependency, you can depend on me.bechberger.ap-loader:<version>-<ap-loader-version>-<variant>-SNAPSHOT
from the Sonatype OSS repository.
See [#usage-in-java-code](Usage in Java Code) for more information. The current ap-loader version is 1
.
Or you can depend on the artifacts from maven central, they should be slightly more stable:
<dependency>
<groupId>me.bechberger</groupId>
<artifactId>ap-loader</artifactId>
<version>2.9-2-all</version>
</dependency>
Others are of course available, see maven central.
- Required Java version: 8 or higher
- Supported OS: Linux and macOS (on all platforms the async-profiler has binaries for)
The JAR can be obtained in the following variants:
macos
,linux-x64
, ...:jattach
,profiler.sh
andlibasyncProfiler.so
for the given platformall
: all of the above
Regarding file sizes: The all
variant are typically around 800KB and the individual variants around 200 to 400KB.
The following is a more in-depth description of the commands of java -jar ap-loader.jar
.
Be aware that it is recommended to use run the JVM with the
-XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints
flags.
This improves the accuracy of the profiler.
Overview of the commands:
Usage: java -jar ap-loader.jar <command> [args]
Commands:
help show this help
jattach run the included jattach binary
profiler run the included profiler.sh
agentpath prints the path of the extracted async-profiler agent
jattachpath prints the path of the extracted jattach binary
supported fails if this JAR does not include a profiler for the current OS and architecture
converter run the included converter
version version of the included async-profiler
clear clear the directory used for storing extracted files
java -jar ap-loader.jar jattach
is equivalent to calling the suitable jattach
binary
from GitHub>:
# Load a native agent
java -jar ap-loader.jar jattach <pid> load <.so-path> { true | false, is path absolute? } [ options ]
# Load a java agent
java -jar ap-loader.jar jattach <pid> load instrument false "javaagent.jar=arguments"
# Running the help command for jcmd
java -jar ap-loader.jar jattach <pid> jcmd "help -all"
See the GitHub page of jattach for more details.
java -jar ap-loader.jar profiler
is equivalent to calling the suitable profiler.sh
:
# Profile a process for `n` seconds
java -jar ap-loader.jar profiler -d <n> <pid>
# Profile a process for allocation, CPU and lock events and save the results to a JFR file
java -jar ap-loader.jar profiler -e alloc,cpu,lock -f <file.jfr> <pid>
See the GitHub page of async-profiler for more details.
Allows you to check whether your JAR includes a jattact
, profile.sh
and libasyncProfiler.so
for
your current OS and architecture.
java -jar ap-loader.jar converter
is equivalent to calling the included converters:
java -jar ap-loader.jar converter <Converter> [options] <input> <output>
# Convert a JFR file to flame graph
java -jar ap-loader.jar converter jfr2flame <input.jfr> <output.html>
The available converters depend on the included async-profiler version.
Call java -jar ap-loader.jar converter
to a list of available converters, see
the source code on GitHub
for more details.
Clear the application directory used for storing extracted files,
like /Users/<user>/Library/Application Support/me.bechberger.ap-loader-<version>/
to redo the extraction on the next run.
java -javaagent:ap-loader.jar=<options>
is equivalent to java -agentpath:libasyncProfiler.so=<options>
with a suitable library.
This can be used to profile a Java process from the start.
# Profile the application and output a flame graph
java -javaagent:ap-loader.jar=start,event=cpu,file=profile.html <java arguments>
See the GitHub page of async-profiler for more details.
Then you can use the AsyncProfilerLoader
class to load the native library:
AsyncProfiler profiler = one.profiler.AsyncProfilerLoader.load();
AsyncProfiler
is
the main API class
from the async-profiler.jar.
The API of the AsyncProfilerLoader
can be used to execute all commands of the CLI programmatically.
The converters reside in the one.converter
package.
<dependency>
<groupId>me.bechberger</groupId>
<artifactId>ap-loader</artifactId>
<version>version-variant</version>
</dependency>
We currently only release to snapshot, as the API is not stable yet.
<dependency>
<groupId>me.bechberger</groupId>
<artifactId>ap-loader</artifactId>
<version>version-variant-SNAPSHOT</version>
</dependency>
For example for the all
variant of version 2.9:
<dependency>
<groupId>me.bechberger</groupId>
<artifactId>ap-loader</artifactId>
<version>2.9-all-SNAPSHOT</version>
</dependency>
You also have to add the snapshot repository:
<repositories>
<repository>
<id>snapshots</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
The following describes how to build the different JARs and how to test them. It requires a platform supported by async-profiler and Python 3.6+.
# download the release sources and binaries
python3 ./bin/releaser.py download 2.9
# build the JAR for the release
# maven might throw warnings, related to the project version setting,
# but the alternative solutions don't work, so we ignore the warning for now
mvn -Dproject.vversion=2.9-macos -Dproject.subrelease=2 -Dproject.platform=macos package assembly:single
# use it
java -jar target/ap-loader-2.9-2-macos-full.jar ...
# build the all JAR
mvn -Dproject.vversion=2.9 -Dproject.subrelease=2 -Dproject.platform=all package assembly:single
This project is written in Java 8, to support all relevant platforms. The feature set should not increase beyond what is currently: Just build your library on top of it. But I'm of course happy for bug reports and fixes.
The code is formatted using google-java-format.
Usage:
python3 ./bin/releaser.py <command> ... <command> [release or current if not present]
Commands:
current_version print the youngest released version of async-profiler
versions print all released versions of async-profiler (supported by this project)
download download and prepare the folders for the given release
build build the wrappers for the given release
test test the given release
deploy_mvn deploy the wrappers for the given release as a snapshot to maven
deploy_gh deploy the wrappers for the given release as a snapshot to GitHub
deploy deploy the wrappers for the given release as a snapshot
deploy_release deploy the wrappers for the given release
clear clear the ap-releases and target folders for a fresh start
Deploy the latest version via bin/releaser.py download build test deploy
as a snapshot.
For a release use bin/releaser.py download build test deploy_release
,
but before make sure to do the following for a new sub release:
- update the version number in the README
- update the changelog in the README and
bin/releaser.py
- and increment the
SUB_VERSION
variable inbin/releaser.py
afterwards
And the following for a new async-profiler release:
- update the version in the README
- Fixed the library version in the pom #3 again (thanks to @gavlyukovskiy, @dpsoft and @krzysztofslusarski for spotting the bug)
- Fixed the library version in the pom #3 (thanks to @gavlyukovskiy for spotting the bug)
- 11.11.2022: Improve Converter
Apache 2.0