Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
title: Setup Tomcat Benchmark Environment
weight: 2

### FIXED, DO NOT MODIFY
layout: learningpathall
---


## Before You Begin
- There are numerous performance analysis methods and tools for Java applications, among which the call stack flame graph method is regarded as a conventional entry-level approach. Therefore, generating flame graphs is considered a basic operation.
- Various methods and tools are available for generating Java flame graphs, including async-profiler, Java Agent, jstack, JFR (Java Flight Recorder), etc.
- This LP (Learning Path) focuses on introducing two simple and easy-to-use methods: async-profiler and Java Agent.


## Setup Benchmark Server - Tomcat
- [Apache Tomcat](https://tomcat.apache.org/) is an open-source Java Servlet container that enables running Java web applications, handling HTTP requests and serving dynamic content.
- As a core component in Java web development, Apache Tomcat supports Servlet, JSP, and WebSocket technologies, providing a lightweight runtime environment for web apps.

1. So you should install Java Development Kit (JDK) first.
```bash
sudo apt update
sudo apt install -y openjdk-21-jdk
```

2. Second, you can install Tomcat by either [building it from source](https://github.com/apache/tomcat) or downloading the pre-built package simply from [the official website](https://tomcat.apache.org/whichversion.html)
```bash
wget -c https://dlcdn.apache.org/tomcat/tomcat-11/v11.0.9/bin/apache-tomcat-11.0.9.tar.gz
tar xzf apache-tomcat-11.0.9.tar.gz
```

3. If you intend to access the built-in Examples of Tomcat via an intranet IP or even an external IP, you need to modify a configuration file.
```bash
vim apache-tomcat-11.0.9/webapps/examples/META-INF/context.xml
# change <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
# to
# <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow=".*" />

# now you can start Tomcat Server
./apache-tomcat-11.0.9/bin/startup.sh
```

4. If you can access the page at "http://${tomcat_ip}:8080/examples" via a browser, congratulations-you can proceed to the next benchmarking step.

![example image alt-text#center](./_images/lp-tomcat-homepage.png "Tomcat-HomePage")

![example image alt-text#center](./_images/lp-tomcat-examples.png "Tomcat-Examples")

## Setup Benchmark Client - [wrk2](https://github.com/giltene/wrk2)
- wrk2 is a high-performance HTTP benchmarking tool specialized in generating constant throughput loads and measuring latency percentiles for web services.
- As an enhanced version of wrk, wrk2 provides accurate latency statistics under controlled request rates, ideal for performance testing of HTTP servers.

1. If you intend to use wrk2, you should install some essential tools before build it.
```bash
sudo apt-get update
sudo apt-get install -y build-essential libssl-dev git zlib1g-dev
```

2. Now you can clone and build it from source.
```bash
sudo git clone https://github.com/giltene/wrk2.git
cd wrk2
sudo make
# move the executable to somewhere in your PATH
sudo cp wrk /usr/local/bin
```

3. Finally, you can run the benchamrk of Tomcat through wrk2.
```bash
wrk -c32 -t16 -R50000 -d60 http://${tomcat_ip}:8080/examples/servlets/servlet/HelloWorldExample
```
Below is the output of wrk2
```console
Running 1m test @ http://172.26.203.139:8080/examples/servlets/servlet/HelloWorldExample
16 threads and 32 connections
Thread calibration: mean lat.: 0.986ms, rate sampling interval: 10ms
Thread calibration: mean lat.: 0.984ms, rate sampling interval: 10ms
Thread calibration: mean lat.: 0.999ms, rate sampling interval: 10ms
Thread calibration: mean lat.: 0.994ms, rate sampling interval: 10ms
Thread calibration: mean lat.: 0.983ms, rate sampling interval: 10ms
Thread calibration: mean lat.: 0.989ms, rate sampling interval: 10ms
Thread calibration: mean lat.: 0.991ms, rate sampling interval: 10ms
Thread calibration: mean lat.: 0.993ms, rate sampling interval: 10ms
Thread calibration: mean lat.: 0.985ms, rate sampling interval: 10ms
Thread calibration: mean lat.: 0.990ms, rate sampling interval: 10ms
Thread calibration: mean lat.: 0.987ms, rate sampling interval: 10ms
Thread calibration: mean lat.: 0.990ms, rate sampling interval: 10ms
Thread calibration: mean lat.: 0.984ms, rate sampling interval: 10ms
Thread calibration: mean lat.: 0.991ms, rate sampling interval: 10ms
Thread calibration: mean lat.: 0.978ms, rate sampling interval: 10ms
Thread calibration: mean lat.: 0.976ms, rate sampling interval: 10ms
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.00ms 454.90us 5.09ms 63.98%
Req/Sec 3.31k 241.68 4.89k 63.83%
2999817 requests in 1.00m, 1.56GB read
Requests/sec: 49997.08
Transfer/sec: 26.57MB
```


Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: Java FlameGraph - Async-profiler
weight: 3

### FIXED, DO NOT MODIFY
layout: learningpathall
---

## Java Flame Graph Generation via async-profiler [async-profiler](https://github.com/async-profiler/async-profiler) (Recommended)
- async-profiler is a low-overhead sampling profiler for JVM applications, capable of capturing CPU, allocation, and lock events to generate actionable performance insights.
- A lightweight tool for Java performance analysis, async-profiler produces flame graphs and detailed stack traces with minimal runtime impact, suitable for production environments.

You should deploy async-profiler on the same machine where Tomcat is running to ensure accurate performance profiling.
1. Download async-profiler-4.0 and uncompress
```bash
wget -c https://github.com/async-profiler/async-profiler/releases/download/v4.0/async-profiler-4.0-linux-arm64.tar.gz
tar xzf async-profiler-4.0-linux-arm64.tar.gz
```

2. Run async-profiler to profile the Tomcat instance under benchmarking
```bash
cd async-profiler-4.0-linux-arm64/bin
./asprof -d 10 -f profile.html $(jps | awk /Bootstrap/'{print $1}')
# or
./asprof -d 10 -f profile.html ${tomcat_process_id}
```

3. Launch profile.html in a browser to analyse the profiling result

![example image alt-text#center](_images/lp-flamegraph-async.png "Java Flame Graph via async-profiler")
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: Java FlameGraph - Java Agent
weight: 4


### FIXED, DO NOT MODIFY
layout: learningpathall
---

## Java Flame Graph Generation via Java agent and perf
To profile a Java application with perf and ensure proper symbol resolution, you must include libperf-jvmti.so when launching the Java application.
- libperf-jvmti.so is a JVM TI agent library enabling perf to resolve Java symbols, facilitating accurate profiling of Java applications.
- A specialized shared library, libperf-jvmti.so bridges perf and the JVM, enabling proper translation of memory addresses to Java method names during profiling.

1. Find and add libperf-jvmti.so to Java option
```bash
vi apache-tomcat-11.0.9/bin/catalina.sh
# add JAVA_OPTS="$JAVA_OPTS -agentpath:/usr/lib/linux-tools-6.8.0-63/libperf-jvmti.so -XX:+PreserveFramePointer"
cd apache-tomcat-11.0.9/bin
./shutdown.sh
./startup.sh
```

2. Use perf to profile Tomcat, and restart wrk if necessary
```bash
sudo perf record -g -k1 -p $(jps | awk /Bootstrap/'{print $1}') -- sleep 10
```

3. Convert the collected perf.data file into a Java flame graph using FlameGraph
```bash
git clone https://github.com/brendangregg/FlameGraph.git
export PATH=$PATH:/root/FlameGraph
sudo perf inject -j -i perf.data | perf script | stackcollapse-perf.pl | flamegraph.pl &> profile.svg
```

4. Launch profile.svg in a browser to analyse the profiling result

![example image alt-text#center](_images/lp-flamegraph-agent.png "Java Flame Graph via Java agent and perf")
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
title: Java Performance Analysis - FlameGraph

draft: true
cascade:
draft: true

minutes_to_complete: 30

who_is_this_for: This is an introductory guide for individuals aiming to perform performance analysis of Java applications on the ARM Neoverse platform using flame graphs.

learning_objectives:
- How to set up tomcat benchmark environment
- How to generate flame graphs for Java applications using async-profiler
- How to generate flame graphs for Java applications using Java agent

prerequisites:
- Basic familiarity with Java applications
- Basic familiarity with flame graphs
- Basic familiarity with Tomcat, wrk, etc

author: Ying Yu, Martin Ma

### Tags
skilllevels: Introductory
subjects: Java Performance Analysis
armips:
- Neoverse

tools_software_languages:
- OpenJDK-21
- Tomcat
- Async-profiler
- FlameGraph
- wrk2
operatingsystems:
- Ubuntu 24


further_reading:
- resource:
title: PLACEHOLDER MANUAL
link: PLACEHOLDER MANUAL LINK
type: documentation
- resource:
title: PLACEHOLDER BLOG
link: PLACEHOLDER BLOG LINK
type: blog
- resource:
title: PLACEHOLDER GENERAL WEBSITE
link: PLACEHOLDER GENERAL WEBSITE LINK
type: website



### FIXED, DO NOT MODIFY
# ================================================================================
weight: 1 # _index.md always has weight of 1 to order correctly
layout: "learningpathall" # All files under learning paths have this same wrapper
learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content.
---
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# ================================================================================
# FIXED, DO NOT MODIFY THIS FILE
# ================================================================================
weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation.
title: "Next Steps" # Always the same, html page title.
layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing.
---
1 change: 1 addition & 0 deletions data/stats_current_test_info.yml
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,4 @@ sw_categories:
zlib:
readable_title: Learn how to build and use Cloudflare zlib on Arm servers
tests_and_status: []

2 changes: 1 addition & 1 deletion data/stats_weekly_data.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7011,4 +7011,4 @@
issues:
avg_close_time_hrs: 0
num_issues: 21
percent_closed_vs_total: 0.0
percent_closed_vs_total: 0.0