Skip to content

Commit 42a324c

Browse files
committed
Run Java applications on the Microsoft Cobalt 100 processors
Signed-off-by: odidev <[email protected]>
1 parent e5c3ba3 commit 42a324c

File tree

13 files changed

+409
-0
lines changed

13 files changed

+409
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
title: Create an Arm based cloud virtual machine using Microsoft Cobalt 100 CPU
3+
weight: 3
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
## Introduction
10+
11+
There are several ways to create an Arm-based Cobalt 100 virtual machine : the Microsoft Azure console, the Azure CLI tool, or using your choice of IaC (Infrastructure as Code). This guide will use the Azure console to create a virtual machine with Arm-based Cobalt 100 Processor.
12+
13+
This learning path focuses on the general-purpose virtual machine of the D series. Please read the guide on [Dpsv6 size series](https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/dpsv6-series) offered by Microsoft Azure.
14+
15+
If you have never used the Microsoft Cloud Platform before, please review the microsoft [guide to Create a Linux virtual machine in the Azure portal](https://learn.microsoft.com/en-us/azure/virtual-machines/linux/quick-create-portal?tabs=ubuntu).
16+
17+
#### Create an Arm-based Azure Virtual Machine
18+
19+
Creating a virtual machine based on Azure Cobalt 100 is no different from creating any other virtual machine in Azure. To create an Azure virtual machine, launch the Azure portal and navigate to "Virtual Machines".
20+
1. Select "Create", and click on "Virtual Machine" from the drop-down list.
21+
2. Inside the "Basic" tab, fill in the Instance details such as "Virtual machine name" and "Region".
22+
3. Choose the image for your virtual machine (for example, Ubuntu 24.04) and select “Arm64” as the VM architecture.
23+
4. In the “Size” field, click on “See all sizes” and select the D-Series v6 family of virtual machines. Select “D4ps_v6” from the list.
24+
25+
![Java Screenshot](images/instance.png)
26+
27+
5. Select "SSH public key" as an Authentication type. Azure will automatically generate an SSH key pair for you and allow you to store it for future use. It is a fast, simple, and secure way to connect to your virtual machine.
28+
6. Fill in the Administrator username for your VM.
29+
7. Select "Generate new key pair", and select "RSA SSH Format" as the SSH Key Type. RSA could offer better security with keys longer than 3072 bits. Give a Key pair name to your SSH key.
30+
8. In the "Inbound port rules", select HTTP (80) and SSH (22) as the inbound ports.
31+
32+
![Java Screenshot](images/instance1.png)
33+
34+
9. Click on the "Review + Create" tab and review the configuration for your virtual machine. It should look like the following:
35+
36+
![Java Screenshot](images/instance2.png)
37+
38+
10. Finally, when you are confident about your selection, click on the "Create" button, and click on the "Download Private key and Create Resources" button.
39+
40+
![Java Screenshot](images/instance4.png)
41+
42+
11. Your virtual machine should be ready and running within no time. You can SSH into the virtual machine using the private key, along with the Public IP details.
43+
44+
![Java Screenshot](images/instance5.png)
45+
46+
{{% notice Note %}}
47+
48+
To learn more about Arm-based virtual machine in Azure, refer to “Getting Started with Microsoft Azure” in [Get started with Arm-based cloud instances](/learning-paths/servers-and-cloud-computing/csp/azure).
49+
50+
{{% /notice %}}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
title: Install Java on Microsoft Azure Virtual Machine
3+
weight: 5
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
10+
11+
## Java Installation on Azure Linux 3.0
12+
Install Java on Azure Linux 3.0 by updating the system and installing `java-devel`, which includes both JRE and JDK. Verify the installation using `java -version` and `javac -version`, then set the `JAVA_HOME` environment variable for Arm-based systems.
13+
14+
15+
### Install Java
16+
17+
This Azure Linux 3.0 image does not include Java, so you need to install it.
18+
19+
First update tdnf:
20+
21+
```console
22+
tdnf update -y
23+
```
24+
Then install java-devel:
25+
26+
```console
27+
tdnf install -y java-devel
28+
```
29+
30+
Java-devel installs both the default JRE and JDK provided by Azure Linux 3.0.
31+
32+
Check to ensure that the JRE is properly installed:
33+
34+
```console
35+
java -version
36+
```
37+
38+
You should see an output similar to:
39+
40+
```output
41+
openjdk version "11.0.27" 2025-04-15 LTS
42+
OpenJDK Runtime Environment Microsoft-11371464 (build 11.0.27+6-LTS)
43+
OpenJDK 64-Bit Server VM Microsoft-11371464 (build 11.0.27+6-LTS, mixed mode,
44+
sharing)
45+
```
46+
47+
Check to ensure that the JDK is properly installed:
48+
49+
```console
50+
javac -version
51+
```
52+
You should see an output similar to:
53+
54+
```output
55+
javac 11.0.27
56+
```
57+
58+
Set Java Environment Variable for Arm:
59+
60+
```console
61+
export JAVA_HOME=/usr/lib/jvm/msopenjdk-11
62+
export PATH=$JAVA_HOME/bin:$PATH
63+
```
64+
65+
{{% notice Note %}}
66+
Azure Linux 3.0 offers the default JDK version 11.0.27. It’s important to ensure that your version of OpenJDK for Arm is at least 11.0.9, or above. There is a large performance gap between OpenJDK-11.0.8 and OpenJDK 11.0.9. A patch added in 11.0.9 reduces false-sharing cache contention.
67+
For more information, you can view this [Arm community blog](https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/java-performance-on-neoverse-n1).
68+
69+
The [Arm Ecosystem Dashboard](https://developer.arm.com/ecosystem-dashboard/) also recommends Java/OpenJDK version 11.0.9 as minimum recommended on the Arm platforms.
70+
{{% /notice %}}
71+
72+
Java installation is complete. You can now proceed with the baseline testing.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
title: Run Java applications on the Microsoft Azure Cobalt 100 processors
3+
4+
minutes_to_complete: 60
5+
6+
who_is_this_for: This Learning Path introduces Java deployment on Microsoft Azure Cobalt 100 (Arm-based) virtual machines. It is designed for developers migrating Java applications from x86_64 to Arm with minimal or no changes.
7+
8+
learning_objectives:
9+
- Provision an Azure Arm64 virtual machine using Azure console, with Ubuntu as the base image.
10+
- Learn how to create an Azure Linux 3.0 Docker container.
11+
- Deploy a Java application inside an Azure Linux 3.0 Arm64-based Docker container and an Azure Linux 3.0 custom-image-based Azure virtual machine.
12+
- Perform Java benchmarking inside the container as well as the custom virtual machine.
13+
14+
prerequisites:
15+
- A [Microsoft Azure](https://azure.microsoft.com/) account with access to Cobalt 100 based instances (Dpsv6).
16+
- A machine with [Docker](/install-guides/docker/) installed.
17+
18+
author: Jason Andrews
19+
20+
### Tags
21+
skilllevels: Advanced
22+
subjects: Performance and Architecture
23+
cloud_service_providers: Microsoft Azure
24+
25+
armips:
26+
- Neoverse
27+
28+
tools_software_languages:
29+
- Java
30+
- Docker
31+
32+
operatingsystems:
33+
- Linux
34+
35+
further_reading:
36+
- resource:
37+
title: Azure Virtual Machines documentation
38+
link: https://learn.microsoft.com/en-us/azure/virtual-machines/
39+
type: documentation
40+
- resource:
41+
title: Azure Container Instances documentation
42+
link: https://learn.microsoft.com/en-us/azure/container-instances/
43+
type: documentation
44+
- resource:
45+
title: Docker overview
46+
link: https://docs.docker.com/get-started/overview/
47+
type: documentation
48+
- resource:
49+
title: Java on Azure
50+
link: https://learn.microsoft.com/en-us/java/azure/
51+
type: documentation
52+
- resource:
53+
title: JMH (Java Microbenchmark Harness) documentation
54+
link: https://openjdk.org/projects/code-tools/jmh/
55+
type: documentation
56+
57+
58+
### FIXED, DO NOT MODIFY
59+
# ================================================================================
60+
weight: 1 # _index.md always has weight of 1 to order correctly
61+
layout: "learningpathall" # All files under learning paths have this same wrapper
62+
learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content.
63+
---
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
# ================================================================================
3+
# FIXED, DO NOT MODIFY THIS FILE
4+
# ================================================================================
5+
weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation.
6+
title: "Next Steps" # Always the same, html page title.
7+
layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing.
8+
---
9+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
title: "About Cobalt 100 Arm-based processor"
3+
4+
weight: 2
5+
6+
layout: "learningpathall"
7+
---
8+
9+
## What is Cobalt 100 Arm-based processor?
10+
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.
12+
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).
14+
15+
## Introduction to Azure Linux 3.0
16+
17+
Azure Linux 3.0 is Microsoft's in-house, lightweight Linux distribution optimized for running cloud-native workloads on Azure. Designed with performance, security, and reliability in mind, it is fully supported by Microsoft and tailored for containers, microservices, and Kubernetes. With native support for Arm64 (AArch64) architecture, Azure Linux 3.0 enables efficient execution of workloads on energy-efficient Arm-based infrastructure, making it a powerful choice for scalable and cost-effective cloud deployments.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
title: Java Baseline Testing
3+
weight: 6
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
10+
### Deploy a Java application with Tomcat-like operation
11+
Apache Tomcat is a Java-based web application server (technically, a Servlet container) that executes Java web applications. It's widely used to host Java servlets, JSP (JavaServer Pages),
12+
and RESTful APIs written in Java.
13+
14+
The below Java class simulates the generation of a basic HTTP response and measures the time taken to construct it, mimicking a lightweight Tomcat-like operation. It measures how long it
15+
takes to build the response string, helping evaluate raw Java execution efficiency before deploying heavier frameworks like Tomcat.
16+
17+
Create a file named `HttpSingleRequestTest.java`, and add the below content to it:
18+
19+
```java
20+
public class HttpSingleRequestTest {
21+
public static void main(String[] args) {
22+
long startTime = System.nanoTime();
23+
String response = generateHttpResponse("Tomcat baseline test on Arm64");
24+
long endTime = System.nanoTime();
25+
double durationInMicros = (endTime - startTime) / 1_000.0;
26+
System.out.println("Response Generated:\n" + response);
27+
System.out.printf("Response generation took %.2f microseconds.%n", durationInMicros);
28+
}
29+
private static String generateHttpResponse(String body) {
30+
return "HTTP/1.1 200 OK\r\n" +
31+
"Content-Type: text/plain\r\n" +
32+
"Content-Length: " + body.length() + "\r\n\r\n" +
33+
body;
34+
}
35+
}
36+
```
37+
Compile and Run Java program :
38+
39+
```console
40+
javac HttpSingleRequestTest.java
41+
java -Xms128m -Xmx256m -XX:+UseG1GC HttpSingleRequestTest
42+
```
43+
44+
- -Xms128m sets the initial heap size for the Java Virtual Machine to 128 MB.
45+
- -Xmx256m sets the maximum heap size for the JVM to 256 MB.
46+
- -XX:+UseG1GC enables the G1 Garbage Collector (Garbage First GC), designed for low pause times and better performance in large heaps.
47+
48+
You should see an output similar to:
49+
```output
50+
51+
Response Generated:
52+
HTTP/1.1 200 OK
53+
Content-Type: text/plain
54+
Content-Length: 29
55+
56+
Tomcat baseline test on Arm64
57+
Response generation took 22125.79 microseconds.
58+
```
59+
Output summary:
60+
61+
- The program generated a fake HTTP 200 OK response with a custom message.
62+
- It then measured and printed the time taken to generate that response (22125.79 microseconds).
63+
- This serves as a basic baseline performance test of string formatting and memory handling on the JVM running on an Azure Arm64 instance.
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
---
2+
title: Benchmarking via JMH
3+
weight: 7
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
Now that you’ve built and run the Tomcat-like response, you can use it to test the JVM performance using JMH. You can also use it to test the performance difference between Cobalt 100 instances and other similar D series x86_64 based instances.
10+
As noted before, the steps to benchmark remain the same, whether it's a Docker container or a custom virtual machine.
11+
12+
## Run the performance tests using JMH
13+
14+
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. It measures the throughput, average latency, or execution time. Below steps help benchmark the Tomcat-like operation:
15+
16+
17+
Install Maven:
18+
19+
```console
20+
tdnf install maven -y
21+
```
22+
Create Benchmark Project:
23+
24+
```console
25+
mvn archetype:generate \
26+
-DinteractiveMode=false \
27+
-DarchetypeGroupId=org.openjdk.jmh \
28+
-DarchetypeArtifactId=jmh-java-benchmark-archetype \
29+
-DarchetypeVersion=1.37 \
30+
-DgroupId=com.example \
31+
-DartifactId=jmh-benchmark \
32+
-Dversion=1.0
33+
cd jmh-benchmark
34+
```
35+
36+
Edit the `src/main/java/com/example/MyBenchmark.java` file and add the below code on it:
37+
38+
```java
39+
package com.example;
40+
import org.openjdk.jmh.annotations.Benchmark;
41+
public class MyBenchmark {
42+
43+
@Benchmarkpublic void benchmarkHttpResponse() {
44+
String body = "Benchmarking a Tomcat-like operation";
45+
StringBuilder sb = new StringBuilder();
46+
sb.append("HTTP/1.1 200 OK\r\n");
47+
sb.append("Content-Type: text/plain\r\n");
48+
sb.append("Content-Length: ").append(body.length()).append("\r\n\r\n");
49+
sb.append(body);
50+
if (sb.length() == 0) throw new RuntimeException(); // avoid DCE }
51+
}
52+
```
53+
This simulates HTTP response generation similar to Tomcat.
54+
55+
Build the Benchmark:
56+
57+
```console
58+
mvn clean install
59+
```
60+
61+
After the build is complete, the JMH benchmark jar will be in the target/ directory.
62+
63+
Run the Benchmark:
64+
65+
```console
66+
java -jar target/benchmarks.jar
67+
```
68+
69+
### Benchmark summary on x86_64:
70+
71+
The following benchmark results are collected on two different x86_64 environments: a **Docker container running Azure Linux 3.0 hosted on a D4s_v6 Ubuntu-based Azure virtual machine**, and a **D4s_v4 Azure virtual machine created from the Azure Linux 3.0 image published by Ntegral Inc**.
72+
73+
| Metric | Value on Docker Container | Value on Virtual Machine
74+
|----------------------------------|----------------------------------------|-------------------|
75+
| **Java Version** | OpenJDK 11.0.27 | OpenJDK 11.0.27 |
76+
| **Run Count** | 25 iterations | 25 iterations |
77+
| **Average Throughput** | 21.88M ops/sec | 15.39M ops/sec |
78+
| **Standard Deviation** | ±0.0769M ops/sec | ±0.17M ops/sec |
79+
| **Confidence Interval (99.9%)**| [21.82M, 21.94M] ops/sec | [14.97M, 15.58M] ops/sec
80+
81+
82+
### Benchmark summary on Arm64:
83+
84+
The following benchmark results are collected on two different Arm64 environments: a **Docker container running Azure Linux 3.0 hosted on a D4ps_v6 Ubuntu-based Azure virtual machine**, and a **D4ps_v6 Azure virtual machine created from the Azure Linux 3.0 custom image using the AArch64 ISO**.
85+
86+
87+
| Metric | Value on Docker Container | Value on Virtual Machine
88+
|----------------------------------|----------------------------------------|-------------------|
89+
| **Java Version** | OpenJDK 11.0.27 | OpenJDK 11.0.27 |
90+
| **Run Count** | 25 iterations | 25 iterations |
91+
| **Average Throughput** | 35.60M ops/sec | 35.48M ops/sec |
92+
| **Standard Deviation** | ±0.1618M ops/sec | ±0.1918M ops/sec |
93+
| **Confidence Interval (99.9%)**| [35.48M, 35.72M] ops/sec | [35.347M, 35.62M] ops/sec
94+
95+
96+
### **Highlights from Azure Linux Arm64 Benchmarking (JDK 11.0.27)**
97+
98+
- **Superior Throughput:** Achieved an average of 35.60M ops/sec on Docker and 35.48M ops/sec on the virtual machine.
99+
- **Stable Performance:** Standard deviation on Docker is ±161,819.485 ops/sec and on the virtual machine is ±191,757.658 ops/sec, indicating consistent benchmarking results.
100+
- **Efficient Execution and Container Feasibility:** Demonstrates the efficiency of the Arm64 architecture for handling high-throughput Java workloads, even within a containerized Azure Linux environment.

0 commit comments

Comments
 (0)