diff --git a/content/learning-paths/servers-and-cloud-computing/java-perf-flamegraph/1_setup.md b/content/learning-paths/servers-and-cloud-computing/java-perf-flamegraph/1_setup.md
index 6fbe8aeb81..e18fb38d9b 100644
--- a/content/learning-paths/servers-and-cloud-computing/java-perf-flamegraph/1_setup.md
+++ b/content/learning-paths/servers-and-cloud-computing/java-perf-flamegraph/1_setup.md
@@ -1,5 +1,5 @@
---
-title: Setup Tomcat Benchmark Environment
+title: Set up Tomcat benchmark environment
weight: 2
### FIXED, DO NOT MODIFY
@@ -8,43 +8,57 @@ layout: learningpathall
## Overview
-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 Learning Path focuses on introducing two simple and easy-to-use methods: `async-profiler` and `Java Agent`.
+Flame graphs are a widely used entry point for analyzing Java application performance. Tools for generating flame graphs include `async-profiler`, Java agents, `jstack`, and Java Flight Recorder (JFR). This Learning Path focuses on two practical approaches: using `async-profiler` and a 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.
+In this section, you'll set up a benchmark environment using Apache Tomcat and `wrk2` to simulate HTTP load and evaluate performance on an Arm-based server.
+
+## Set up the Tomcat benchmark server
+[Apache Tomcat](https://tomcat.apache.org/) is an open-source Java Servlet container that runs Java web applications, handles HTTP requests, and serves dynamic content. It supports technologies such as Servlet, JSP, and WebSocket.
+
+## Install the Java Development Kit (JDK)
+
+Install OpenJDK 21 on your Arm-based Ubuntu server:
-1. Start by installing Java Development Kit (JDK) on your Arm-based server running Ubuntu:
```bash
sudo apt update
sudo apt install -y openjdk-21-jdk
```
-2. Next, 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)
+## Install Tomcat
+
+Download and extract Tomcat:
+
```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
```
+Alternatively, you can build Tomcat [from source](https://github.com/apache/tomcat).
+
+## Enable access to Tomcat examples
+
+To access the built-in examples from your local network or external IP, modify the `context.xml` file:
-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 as shown:
```bash
vi apache-tomcat-11.0.9/webapps/examples/META-INF/context.xml
```
-Then change the allow value as shown and save the changes:
-```output
-# change
-# to
+Update the `RemoteAddrValve` configuration to allow all IPs:
+
+
+
+
+
-```
-Now you can start Tomcat Server:
+
+## Start the Tomcat server
+
+Start the server:
+
```bash
./apache-tomcat-11.0.9/bin/startup.sh
```
-The output from starting the server should look like:
+You should see output like:
```output
Using CATALINA_BASE: /home/ubuntu/apache-tomcat-11.0.9
@@ -56,42 +70,58 @@ Using CATALINA_OPTS:
Tomcat started.
```
-4. If you can access the page at "http://${tomcat_ip}:8080/examples" via a browser, you can proceed to the next benchmarking step.
+## Confirm server access
+
+In your browser, open: `http://${tomcat_ip}:8080/examples`.
+
+You should see the Tomcat welcome page and examples, as shown below:
+
+
-
+
-
+{{% notice Note %}}Make sure port 8080 is open in the security group of the IP address for your Arm-based Linux machine.{{% /notice%}}
-Make sure port 8080 is open in the security group of the IP address for your Arm-based Linux machine.
+## Set up the benchmarking client using wrk2
+[Wrk2](https://github.com/giltene/wrk2) is a high-performance HTTP benchmarking tool specialized in generating constant throughput loads and measuring latency percentiles for web services. `wrk2` is an enhanced version of `wrk` that provides accurate latency statistics under controlled request rates, ideal for performance testing of HTTP servers.
-## 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. `wrk2` is an enhanced version of `wrk` that provides accurate latency statistics under controlled request rates, ideal for performance testing of HTTP servers.
+{{% notice Note %}}
+Currently `wrk2` is only supported on x86 machines. Run the benchmark client steps below on an `x86_64` server running Ubuntu.
+{{%/notice%}}
-Currently `wrk2` is only supported on x86 machines. You will run the Benchmark Client steps shown below on an x86_64 server running Ubuntu.
+## Install dependencies
+Install the required packages:
-1. To use `wrk2`, you will need to install some essential tools before you can 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:
+## Clone and build wrk2
+
+Clone the repository and compile the tool:
+
```bash
sudo git clone https://github.com/giltene/wrk2.git
cd wrk2
sudo make
```
-Move the executable to somewhere in your PATH:
+
+Move the binary to a directory in your system’s PATH:
+
```bash
sudo cp wrk /usr/local/bin
```
-3. Finally, you can run the benchmark of Tomcat through wrk2.
+## Run the benchmark
+
+Use the following command to benchmark the HelloWorld servlet running on Tomcat:
+
```bash
wrk -c32 -t16 -R50000 -d60 http://${tomcat_ip}:8080/examples/servlets/servlet/HelloWorldExample
```
-Shown below is the output of wrk2:
+You should see output similar to:
```console
Running 1m test @ http://172.26.203.139:8080/examples/servlets/servlet/HelloWorldExample
diff --git a/content/learning-paths/servers-and-cloud-computing/java-perf-flamegraph/2_async-profiler.md b/content/learning-paths/servers-and-cloud-computing/java-perf-flamegraph/2_async-profiler.md
index 5346d45fac..cd1f236620 100644
--- a/content/learning-paths/servers-and-cloud-computing/java-perf-flamegraph/2_async-profiler.md
+++ b/content/learning-paths/servers-and-cloud-computing/java-perf-flamegraph/2_async-profiler.md
@@ -1,32 +1,54 @@
---
-title: Java FlameGraph - Async-profiler
+title: Generate Java flame graphs using async-profiler
weight: 3
### FIXED, DO NOT MODIFY
layout: learningpathall
---
-## Java Flame Graph Generation using [async-profiler](https://github.com/async-profiler/async-profiler)
-`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. In this section, you will learn how to install and use it to profile your Tomcat instance being benchmarked.
+## Overview
+
+[Async-profiler](https://github.com/async-profiler/async-profiler) is a low-overhead sampling profiler for JVM applications. It can capture CPU usage, memory allocations, and lock events to generate flame graphs and detailed stack traces.
+
+
+This tool is well-suited for production environments due to its minimal runtime impact. In this section, you'll install and run `async-profiler` to analyze performance on your Tomcat instance under benchmark load.
+
+{{%notice Note%}}
+Install and run `async-profiler` on the same Arm-based Linux machine where Tomcat is running to ensure accurate profiling.
+{{%/notice%}}
+
+## Install async-profiler
+
+Download and extract the latest release:
-You should deploy `async-profiler` on the same Arm Linux 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
+## Run the profiler
+
+Navigate to the profiler binary directory:
+
```bash
cd async-profiler-4.0-linux-arm64/bin
-./asprof -d 10 -f profile.html $(jps | awk /Bootstrap/'{print $1}')
```
-You can also run:
+Run async-profiler against the Tomcat process:
+
+```bash
+./asprof -d 10 -f profile.html $(jps | awk /Bootstrap/'{print $1}')
```
+Alternatively, if you already know the process ID (PID):
+
+```bash
./asprof -d 10 -f profile.html ${tomcat_process_id}
```
+* `-d 10` sets the profiling duration to 10 seconds
+
+* `-f profile.html` specifies the output file
+
+## View the flame graph
-3. Now launch `profile.html` in a browser to analyse your profiling result
+Open the generated `profile.html` file in a browser to view your Java flame graph:
-
+
diff --git a/content/learning-paths/servers-and-cloud-computing/java-perf-flamegraph/3_agent.md b/content/learning-paths/servers-and-cloud-computing/java-perf-flamegraph/3_agent.md
index 96ff1ea117..c2de6d84a4 100644
--- a/content/learning-paths/servers-and-cloud-computing/java-perf-flamegraph/3_agent.md
+++ b/content/learning-paths/servers-and-cloud-computing/java-perf-flamegraph/3_agent.md
@@ -1,5 +1,5 @@
---
-title: Java FlameGraph - Java Agent
+title: Generate Java flame graphs using a Java agent
weight: 4
@@ -7,42 +7,66 @@ weight: 4
layout: learningpathall
---
-## Java Flame Graph Generation using 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.
+## Overview
+
+You can profile a Java application using `perf` by including a Java agent that enables symbol resolution. This allows `perf` to capture meaningful method names instead of raw memory addresses.
+
+The required library is `libperf-jvmti.so`, a JVM Tool Interface (JVMTI) agent that bridges `perf` and the JVM. It ensures that stack traces collected during profiling can be accurately resolved to Java methods.
+
+In this section, you'll configure Tomcat to use this Java agent and generate a flame graph using the FlameGraph toolkit.
+
+## Locate the Java agent
+
+Locate the `libperf-jvmti.so` library:
-1. Find where `libperf-jvmti.so` is installed on your Arm-based Linux server:
```bash
pushd /usr/lib
find . -name libperf-jvmti.so`
```
-The output will show the path of the library that you will then include in your Tomcat setup file:
+The output will show the path to the shared object file:
+
+## Modify Tomcat configuration
+
+Open the Tomcat launch script:
+
```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" to `catalina.sh`. Make sure the path matches the location on your machine from the previous step.
+Add the following line (replace the path if different on your system):
+```bash
+JAVA_OPTS="$JAVA_OPTS -agentpath:/usr/lib/linux-tools-6.8.0-63/libperf-jvmti.so -XX:+PreserveFramePointer"
+```
Now shutdown and restart Tomcat:
+
```bash
cd apache-tomcat-11.0.9/bin
./shutdown.sh
./startup.sh
```
-2. Use perf to profile Tomcat, and restart wrk that running on your x86 instance if necessary:
+## Run perf to record profiling data
+
+Run the following command to record a 10-second profile of the Tomcat process:
+
```bash
sudo perf record -g -k1 -p $(jps | awk /Bootstrap/'{print $1}') -- sleep 10
```
-This command will record the collected data in a file named `perf.data`
+This generates a file named `perf.data`.
+
+If needed, restart `wrk` on your x86 client to generate load during profiling.
+
+## Generate a flame graph
+
+Clone the FlameGraph repository and add it to your PATH:
-3. Convert the collected `perf.data` into a Java flame graph using FlameGraph
```bash
git clone https://github.com/brendangregg/FlameGraph.git
export PATH=$PATH:`pwd`/FlameGraph
sudo perf inject -j -i perf.data | perf script | stackcollapse-perf.pl | flamegraph.pl &> profile.svg
```
+## View the result
-4. You can now successfully launch `profile.svg` in a browser to analyse the profiling result
+You can now launch `profile.svg` in a browser to analyse the profiling result:
-
+
diff --git a/content/learning-paths/servers-and-cloud-computing/java-perf-flamegraph/_index.md b/content/learning-paths/servers-and-cloud-computing/java-perf-flamegraph/_index.md
index 06a3c9281c..b675188fa3 100644
--- a/content/learning-paths/servers-and-cloud-computing/java-perf-flamegraph/_index.md
+++ b/content/learning-paths/servers-and-cloud-computing/java-perf-flamegraph/_index.md
@@ -1,57 +1,49 @@
---
-title: Analyze Java Performance on Arm servers using FlameGraphs
-
-draft: true
-cascade:
- draft: true
-
+title: Analyze Java performance on Arm servers using flame graphs
minutes_to_complete: 30
-who_is_this_for: This is an introductory topic for software developers looking to analyze the performance of their Java applications on the Arm Neoverse based servers using flame graphs.
+who_is_this_for: This is an introductory topic for developers who want to analyze the performance of Java applications on Arm Neoverse-based servers 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
+ - Set up a benchmarking environment using Tomcat and wrk2
+ - Generate flame graphs using async-profiler
+ - Generate flame graphs using a Java agent
prerequisites:
- - An Arm-based and x86 computer running Ubuntu. You can use a server instance from a cloud service provider of your choice.
- - Basic familiarity with Java applications and flame graphs
+ - Access to both Arm-based and x86-based computers running Ubuntu (you can use cloud-based server instances)
+ - Basic familiarity with Java applications and performance profiling using flame graphs
-author: Ying Yu, Martin Ma
+author:
+ - Ying Yu
+ - Martin Ma
-### Tags
+# Tags
skilllevels: Introductory
subjects: Performance and Architecture
armips:
- - Neoverse
-
+ - Neoverse
+
tools_software_languages:
- - OpenJDK-21
- - Tomcat
- - Async-profiler
- - FlameGraph
- - wrk2
-operatingsystems:
- - Linux
+ - OpenJDK-21
+ - Tomcat
+ - async-profiler
+ - FlameGraph
+ - wrk2
+operatingsystems:
+ - Linux
further_reading:
- - resource:
- title: OpenJDK Wiki
- link: https://wiki.openjdk.org/
- type: documentation
- - resource:
- title: Java FlameGraphs
- link: https://www.brendangregg.com/flamegraphs.html
- 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.
+ - resource:
+ title: OpenJDK Wiki
+ link: https://wiki.openjdk.org/
+ type: documentation
+ - resource:
+ title: Java FlameGraphs
+ link: https://www.brendangregg.com/flamegraphs.html
+ type: website
+
+weight: 1
+layout: "learningpathall"
+learning_path_main_page: "yes"
---