Skip to content

Commit 3fe7d86

Browse files
Merge pull request #2348 from madeline-underwood/Java_apps_Cobalt
Java apps cobalt_JA to sign off
2 parents f1c6db0 + 49547f2 commit 3fe7d86

File tree

6 files changed

+140
-121
lines changed

6 files changed

+140
-121
lines changed

content/learning-paths/servers-and-cloud-computing/java-on-azure/_index.md

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
---
2-
title: Deploy Java applications on the Microsoft Azure Cobalt 100 processors
3-
4-
draft: true
5-
cascade:
6-
draft: true
2+
title: Deploy Java applications on Azure Cobalt 100 processors
73

84
minutes_to_complete: 30
95

10-
who_is_this_for: This is an introductory topic about Java deployment and benchmarking on Microsoft Azure Cobalt 100 (Arm-based) virtual machines. It is designed for developers migrating Java applications from x86_64 to Arm.
6+
who_is_this_for: This is an introductory topic about Java deployment and benchmarking on Microsoft Azure Cobalt 100 Arm-based virtual machines. It is designed for developers migrating Java applications from x86_64 to Arm architecture.
117

128
learning_objectives:
13-
- Provision an Azure Arm-based Cobalt 100 virtual machine using Azure console, with Ubuntu Pro 24.04 LTS as the base image.
14-
- Deploy Java on the Azure Arm64 virtual machine.
15-
- Perform Java baseline testing and benchmarking on the Arm64 virtual machines.
9+
- Provision an Azure Arm-based Cobalt 100 virtual machine using Azure console, with Ubuntu Pro 24.04 LTS as the base image
10+
- Deploy Java on the Azure Arm64 virtual machine
11+
- Perform Java baseline testing and benchmarking on the Arm64 virtual machines
1612

1713
prerequisites:
18-
- A [Microsoft Azure](https://azure.microsoft.com/) account with access to Cobalt 100 based instances (Dpsv6).
14+
- A [Microsoft Azure](https://azure.microsoft.com/) account with access to Cobalt 100 based instances (Dpsv6)
1915

2016

2117
author: Pareena Verma

content/learning-paths/servers-and-cloud-computing/java-on-azure/background.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@ weight: 2
66
layout: "learningpathall"
77
---
88

9-
## Cobalt 100 Arm-based processor
9+
## Azure Cobalt 100 Arm-based CPU for Linux workloads
1010

11-
Azure’s Cobalt 100 is built on Microsoft's first-generation, in-house Arm-based processor: the Cobalt 100. Designed entirely by Microsoft and based on Arm’s Neoverse N2 architecture, this 64-bit CPU delivers improved performance and energy efficiency across a broad spectrum of cloud-native, scale-out Linux workloads. These include web and application servers, data analytics, open-source databases, caching systems, and more. Running at 3.4 GHz, the Cobalt 100 processor allocates a dedicated physical core for each vCPU, ensuring consistent and predictable performance.
11+
Azure Cobalt 100 is Microsofts firstgeneration, inhouse Armbased CPU built on Arm Neoverse N2. It is designed for predictable performance and energy efficiency across common Linux workloads such as web and application servers, analytics, opensource databases, and caching systems. Each vCPU maps to a dedicated physical core and runs up to **3.4 GHz**, helping deliver consistent latency under load.
1212

13-
To learn more about Cobalt 100, refer to the blog [Announcing the preview of new Azure virtual machine based on the Azure Cobalt 100 processor](https://techcommunity.microsoft.com/blog/azurecompute/announcing-the-preview-of-new-azure-vms-based-on-the-azure-cobalt-100-processor/4146353).
13+
Learn more in this Microsoft announcement blog: [Announcing the preview of new Azure VMs based on the Azure Cobalt 100 processor](https://techcommunity.microsoft.com/blog/azurecompute/announcing-the-preview-of-new-azure-vms-based-on-the-azure-cobalt-100-processor/4146353).
1414

15-
## Java
16-
Java is a high-performance, open-source, object-oriented programming language and runtime environment widely used for building scalable, reliable, and secure applications.
15+
## Running Java on Azure Cobalt 100 Arm-based VMs
16+
17+
Java is a mature, object‑oriented language and runtime used to build scalable, secure applications. The Java Virtual Machine (JVM) executes platform‑independent bytecode, enabling *write once, run anywhere* portability across architectures, including Arm64 (AArch64). On Azure Cobalt 100, Java services benefit from modern JIT compilers and efficient multithreading for steady throughput and low tail latency.
18+
19+
Learn more with these resources:
20+
- Visit the [OpenJDK website](https://openjdk.org/).
21+
- See the [Java documentation](https://docs.oracle.com/en/java/).
1722

18-
It enables developers to write code once and run it anywhere, thanks to the Java Virtual Machine (JVM), which abstracts away hardware and operating system differences. Java applications are compiled into bytecode, which the JVM executes, providing portability and performance across platforms.
1923

20-
Java is extensively used in enterprise systems, cloud-native applications, Android development, big data processing, and high-performance computing. Learn more from the [OpenJDK official website](https://openjdk.org/) and its [official documentation](https://docs.oracle.com/en/java/).

content/learning-paths/servers-and-cloud-computing/java-on-azure/baseline.md

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,20 @@ layout: learningpathall
77
---
88

99

10-
### Deploy a Java application with a Tomcat-like operation
11-
Apache Tomcat is a widely used Java web application server. Technically, it is a Servlet container, responsible for executing Java servlets and supporting technologies like:
10+
## Deploy a Java application with a Tomcat-like operation
11+
Apache Tomcat is a widely used Java web application server. Technically, it is a Servlet container, responsible for executing Java servlets and supporting technologies such as:
1212

13-
* JSP (JavaServer Pages): Java-based templates for dynamic web content.
14-
* RESTful APIs: Lightweight endpoints for modern microservices.
13+
- JSP (JavaServer Pages): Java-based templates for dynamic web content
14+
- RESTful APIs: lightweight endpoints for modern microservices
1515

16-
In production, frameworks like Tomcat introduce additional complexity (request parsing, thread management, I/O handling). Before layering those components, it's useful to measure how efficiently raw Java executes simple request/response logic on Azure Cobalt 100 Arm-based instances.
16+
In production, frameworks like Tomcat introduce additional complexity (such as request parsing, thread management, and I/O handling). Before layering those components, it's useful to measure how efficiently raw Java executes simple request/response logic on Azure Cobalt 100 Arm-based instances.
1717

18-
In this section, you will run a minimal Tomcat-like simulation. It won't launch a real server, but instead it:
19-
* Constructs a basic HTTP response string in memory.
20-
* Measures the time taken to build that response, acting as a microbenchmark.
21-
* Provides a baseline for raw string and I/O handling performance in Java.
18+
In this section, you will run a minimal Tomcat-like simulation. It won't launch a real server, but instead it will do the following:
19+
- Construct a basic HTTP response string in memory
20+
- Measure the time taken to build that response, acting as a microbenchmark
21+
- Provide a baseline for raw string and I/O handling performance in Java
2222

23-
Using a file editor of your choice create a file named `HttpSingleRequestTest.java`, and add the content below to it:
23+
Using a file editor of your choice, create a file named `HttpSingleRequestTest.java`, and add the content below to it:
2424

2525
```java
2626
public class HttpSingleRequestTest {
@@ -40,18 +40,25 @@ public class HttpSingleRequestTest {
4040
}
4141
}
4242
```
43-
Compile and Run Java program :
43+
## Compile and run the Java program
44+
45+
Compile the program and run it with modest heap sizes and the G1 garbage collector:
4446

4547
```console
4648
javac HttpSingleRequestTest.java
4749
java -Xms128m -Xmx256m -XX:+UseG1GC HttpSingleRequestTest
4850
```
4951

50-
- -Xms128m sets the initial heap size for the Java Virtual Machine to 128 MB.
51-
- -Xmx256m sets the maximum heap size for the JVM to 256 MB.
52-
- -XX:+UseG1GC enables the G1 Garbage Collector (Garbage First GC), designed for low pause times and better performance in large heaps.
52+
## JVM flags explained
53+
54+
- **-Xms128m** - sets the initial heap size to 128 MB
55+
- **-Xmx256m** - sets the maximum heap size to 256 MB
56+
- **-XX:+UseG1GC** - enables the G1 garbage collector designed for low pause times
57+
58+
## Sample output
59+
60+
If the program runs successfully, you should see output similar to the following:
5361

54-
You should output similar to:
5562
```output
5663
java -Xms128m -Xmx256m -XX:+UseG1GC HttpSingleRequestTest
5764
Response Generated:
@@ -62,11 +69,21 @@ Content-Length: 29
6269
Tomcat baseline test on Arm64
6370
Response generation took 12901.53 microseconds.
6471
```
65-
Output breakdown:
6672

67-
Generated Response: The program generates a fake HTTP 200 OK response with headers and a custom body string.
68-
Timing Result: The program prints how long it took (in microseconds) to build that response.
69-
In this example, it took ~12,901 µs (~12.9 ms). Your result will vary depending on CPU load, JVM warm-up, and environment.
73+
## Output breakdown
74+
75+
- Generated response: the program prints a fake HTTP 200 OK response with headers and a custom body string
76+
- Timing result: the program prints how long it took (in microseconds) to build that response
77+
- Variability: results change with CPU load, JVM warm‑up, and environment; run several times and use the median
78+
79+
{{% notice Tip %}}
80+
For repeatable baselines on Azure Cobalt 100, keep other workloads off the VM, use consistent power settings, and keep OS/JDK versions fixed during comparisons. For statistics and warmups, wrap this code with **JMH**.
81+
{{% /notice %}}
82+
83+
## Why this baseline matters
84+
85+
- Provides a Tomcat‑like request path without container overhead
86+
- Enables x86_64 vs Arm64 comparisons on identical code and flags
87+
- Informs GC and flag choices before testing full frameworks like Tomcat, Jetty, or Netty
88+
7089

71-
This provides you with a baseline measurement of how Java handles simple string operations and memory allocation on Cobalt 100 (Arm64) instances.
72-
It serves as a lightweight proxy for Tomcat-style request handling before adding the full complexity of a servlet container.

content/learning-paths/servers-and-cloud-computing/java-on-azure/benchmarking.md

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,32 @@
1+
12
---
2-
title: Benchmarking via JMH
3+
title: Benchmark using Java Microbenchmark Harness
34
weight: 6
45

56
### FIXED, DO NOT MODIFY
67
layout: learningpathall
78
---
9+
## Overview
810

911
Now that you have built and run a Tomcat-like response in Java, the next step is to benchmark it using a reliable, JVM-aware framework.
1012

1113
## Run performance tests using JMH
1214

13-
JMH (Java Microbenchmark Harness) is a Java benchmarking framework developed by the JVM team at Oracle to measure the performance of small code snippets with high precision. It accounts for JVM optimizations like JIT and warm-up to ensure accurate and reproducible results. You can measure throughput (ops/sec), average execution time, or percentiles for latency.
15+
JMH (Java Microbenchmark Harness) is a Java benchmarking framework developed by the JVM team at Oracle to measure the performance of small code snippets with high precision. It accounts for JVM optimizations like JIT and warmup to ensure accurate and reproducible results. You can measure throughput (ops/sec), average execution time, or percentiles for latency.
1416

1517
Follow the steps to help benchmark the Tomcat-like operation with JMH:
1618

1719

1820
Install Maven:
1921

2022
```console
21-
sudo apt install maven -y
23+
sudo apt update
24+
sudo apt install -y maven
2225
```
2326
Once Maven is installed, create a JMH benchmark project using the official archetype provided by OpenJDK:
2427

2528
```console
26-
mvn archetype:generate \
27-
-DinteractiveMode=false \
28-
-DarchetypeGroupId=org.openjdk.jmh \
29-
-DarchetypeArtifactId=jmh-java-benchmark-archetype \
30-
-DarchetypeVersion=1.37 \
31-
-DgroupId=com.example \
32-
-DartifactId=jmh-benchmark \
33-
-Dversion=1.0
29+
mvn archetype:generate -DinteractiveMode=false -DarchetypeGroupId=org.openjdk.jmh -DarchetypeArtifactId=jmh-java-benchmark-archetype -DarchetypeVersion=1.37 -DgroupId=com.example -DartifactId=jmh-benchmark -Dversion=1.0
3430
cd jmh-benchmark
3531
```
3632
The output should look like:
@@ -84,10 +80,12 @@ public class MyBenchmark {
8480
```
8581
This mirrors the Tomcat-like simulation you created earlier but now runs under JMH.
8682

87-
Build the Benchmark JAR:
83+
## Build the benchmark JAR
84+
85+
Build the project to produce the benchmark JAR:
8886

8987
```console
90-
mvn clean install
88+
mvn clean install -q
9189
```
9290

9391
The output from this command should look like:
@@ -104,7 +102,7 @@ The output from this command should look like:
104102

105103
After the build is complete, the JMH benchmark JAR will be located in the target directory.
106104

107-
Run the Benchmark:
105+
Run the benchmark:
108106

109107
```console
110108
java -jar target/benchmarks.jar
@@ -205,8 +203,7 @@ Each iteration shows how many times per second your `benchmarkHttpResponse()` me
205203
REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
206204
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
207205
experiments, perform baseline and negative tests that provide experimental control, make sure
208-
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
209-
Do not assume the numbers tell you what you want them to tell.
206+
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts. Do not assume the numbers tell you what you want them to tell.
210207
211208
NOTE: Current JVM experimentally supports Compiler Blackholes, and they are in use. Please exercise
212209
extra caution when trusting the results, look into the generated code to check the benchmark still
@@ -218,34 +215,34 @@ Benchmark Mode Cnt Score Error Units
218215
MyBenchmark.benchmarkHttpResponse thrpt 25 35659618.044 ± 686946.011 ops/s
219216
```
220217

221-
### Benchmark Metrics Explained
218+
## Benchmark metrics explained
222219

223-
- **Run Count**: The total number of benchmark iterations that JMH executed. More runs improve statistical reliability and help smooth out anomalies caused by the JVM or OS.
224-
- **Average Throughput**: The mean number of operations completed per second across all measured iterations. This is the primary indicator of sustained performance for the benchmarked code.
225-
- **Standard Deviation**: Indicates the amount of variation or dispersion from the average throughput. A smaller standard deviation means more consistent performance.
226-
- **Confidence Interval (99.9%)**: The statistical range in which the true average throughput is expected to fall with 99.9% certainty. Narrow confidence intervals suggest more reliable and repeatable measurements.
227-
- **Min Throughput**: The lowest observed throughput across all iterations, representing a worst-case scenario under the current test conditions.
228-
- **Max Throughput**: The highest observed throughput across all iterations, representing the best-case performance under the current test conditions.
220+
- **Run count** - the total number of benchmark iterations that JMH executed. More runs improve statistical reliability and help smooth out anomalies caused by the JVM or OS.
221+
- **Average throughput** - the mean number of operations completed per second across all measured iterations. This is the primary indicator of sustained performance for the benchmarked code.
222+
- **Standard deviation** - indicates the amount of variation or dispersion from the average throughput. A smaller standard deviation means more consistent performance.
223+
- **Confidence interval (99.9%)** - the statistical range in which the true average throughput is expected to fall with 99.9% certainty. Narrow confidence intervals suggest more reliable and repeatable measurements.
224+
- **Min throughput** - the lowest observed throughput across all iterations, representing a worst-case scenario under the current test conditions.
225+
- **Max throughput** - the highest observed throughput across all iterations, representing the best-case performance under the current test conditions.
229226

230-
### Benchmark summary on Arm64
227+
## Benchmark summary on Arm64
231228

232229
Here is a summary of benchmark results collected on an Arm64 **D4ps_v6 Ubuntu Pro 24.04 LTS virtual machine**.
233230
| Metric | Value |
234231
|--------------------------------|---------------------------|
235-
| **Java Version** | OpenJDK 21.0.8 |
236-
| **Run Count** | 25 iterations |
237-
| **Average Throughput** | 35.66M ops/sec |
238-
| **Standard Deviation** | ±0.92M ops/sec |
239-
| **Confidence Interval (99.9%)**| [34.97M, 36.34M] ops/sec |
240-
| **Min Throughput** | 33.53M ops/sec |
241-
| **Max Throughput** | 36.99M ops/sec |
232+
| **Java version** | OpenJDK 21.0.8 |
233+
| **Run count** | 25 iterations |
234+
| **Average throughput** | 35.66M ops/sec |
235+
| **Standard deviation** | ±0.92M ops/sec |
236+
| **Confidence interval (99.9%)**| [34.97M, 36.34M] ops/sec |
237+
| **Min throughput** | 33.53M ops/sec |
238+
| **Max throughput** | 36.99M ops/sec |
242239

243240

244-
### Key insights from the results
241+
## Key insights from the results
245242

246-
- **Strong throughput performance** The benchmark sustained around 35.6 million operations per second, demonstrating efficient string construction and memory handling on the Arm64 JVM.
247-
- **Consistency across runs** With a standard deviation under 1 million ops/sec, results were tightly clustered. This suggests stable system performance without significant noise from background processes.
248-
- **High statistical confidence** The narrow 99.9% confidence interval ([34.97M, 36.34M]) indicates reliable, repeatable results.
249-
- **Predictable performance envelope** The difference between min (33.5M) and max (37.0M) throughput is modest (~10%), suggests the workload performed consistently without extreme slowdowns or spikes.
243+
- **Strong throughput performance** - the benchmark sustained around 35.6 million operations per second, demonstrating efficient string construction and memory handling on the Arm64 JVM.
244+
- **Consistency across runs** - with a standard deviation under 1 million ops/sec, results were tightly clustered. This suggests stable system performance without significant noise from background processes.
245+
- **High statistical confidence** - the narrow 99.9% confidence interval ([34.97M, 36.34M]) indicates reliable, repeatable results.
246+
- **Predictable performance envelope** - the difference between min (33.5M) and max (37.0M) throughput is modest (~10%), suggests the workload performed consistently without extreme slowdowns or spikes.
250247

251248
The Arm-based Azure `D4ps_v6` VM provides stable and efficient performance for Java workloads, even in microbenchmark scenarios. These results establish a baseline you can now compare directly against x86_64 instances to evaluate relative performance.

0 commit comments

Comments
 (0)