Simple Java Sampling Wrapper (SJSW) is a async-profiler Java wrapper library that attaches
async-profiler
to external Java process as an agent.
SJSW currently can:
This project is part of my bachelor's thesis Examination of Performance Change Detection Efficiency Using Sampling and Instrumentation Techniques
(2024-2025).
Regardless in what mode (standalone or integrated as a lib) you plan to use SJSW, you need to adjust the configuration.
Configuration file looks like this:
{
"classPath": "/path/.../exampleProject/target/classes",
"mainClass": "com.example.benchmark.Benchmark",
"profilerPath": "/home/test/tmp/async-profiler/build/lib/libasyncProfiler.so",
"outputPath": "/home/test/output.sampler.json",
"profilerRawOutputPath": "/home/test/asprof.sjsw.output.raw.json"
}
Be advised, that the configuration file can be overridden by Java arguments if they are supplied in the same order as they are in the config.json
.
classPath
: folder where compiled Java classes of the benchmark application reside, or a location of a text file (*.txt) with all classpaths.
mainClass
: main class coordinates of the benchmark application
profilerPath
: path to the async-profiler executable file. If you're using Linux or MacOS, you can use ones already included in this project:
async-profiler executables for Linux and MacOS are included in this project:
For linux: ./executables/linux/lib/libasyncProfiler.so
For MacOS: ./executables/macos/lib/libasyncProfiler.so
outputPath
: output path of internal SJSW structure. In the next release, this will be changed to the serialized output of the call stack tree.
profilerRawOutputPath
: raw output path of async-profiler.
If you want to use SJSW in you own project:
private static final SamplerExecutorPipeline executor = new AsyncProfilerExecutor();
Retrieve configuration
Config CONFIGURATION = Config.retrieveConfiguration(new File("config.json"));
// OR
Config CONFIGURATION = Config.retrieveConfiguration(args);
execute
method to start Java application with async-profiler attached, and execute write
method afterward to record results to a file.
executor.execute(CONFIGURATION, Duration.ofSeconds(8));
executor.write(CONFIGURATION.outputPath());
Make sure you use SJSW with JDK17.
In config.json adjust profilerPath
value to either your local path of libasyncProfiler.so
, or to relative path of already included async-profiler executables (see Configuration File)
Execute to allow event access for unprivileged users (non sudo users)
sudo sysctl kernel.perf_event_paranoid=1
Adjust values remaining values in config.json like described in Configuration File section that are specific to your benchmark project.
Execute StandaloneSampler as main, or use the SamplerExecutorPipeline like it is described in Using as a Library
Raw output and the tree should be outputted to the console.