Skip to content

Commit c1505fb

Browse files
authored
Merge pull request #1422 from pareenaverma/content_review
Tech review of Java GC LP
2 parents 640c711 + 3e7af81 commit c1505fb

File tree

6 files changed

+62
-64
lines changed

6 files changed

+62
-64
lines changed

content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Example_application.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ layout: learningpathall
88

99
## Example Application.
1010

11-
Copy and paste the following Java snippet into a file called `HeapUsageExample.java`. This code example allocates 1 million string objects to fill up the heap. We can use this example to easily observe the effects of different GC tuning parameters.
11+
Using a file editor of your choice, copy the Java snippet below into a file named `HeapUsageExample.java`. This code example allocates 1 million string objects to fill up the heap. You can use this example to easily observe the effects of different GC tuning parameters.
1212

1313
```java
1414
public class HeapUsageExample {
@@ -34,26 +34,28 @@ public class HeapUsageExample {
3434

3535
### Enable GC logging
3636

37-
To observe the what the GC is doing, one option is to enabling logging whilst the JVM is running. To enable this, we need to pass in some command-line arguments. The `gc` option logs the GC information we are interested. The `filecount` option creates a rolling log to prevent uncontrolled growth of logs with the drawback that historical logs may be rewritten and lost. Run the following command from the terminal to enable logging on JDK 11 onwards.
37+
To observe what the GC is doing, one option is to enabling logging while the JVM is running. To enable this, you need to pass in some command-line arguments. The `gc` option logs the GC information. The `filecount` option creates a rolling log to prevent uncontrolled growth of logs with the drawback that historical logs may be rewritten and lost. Run the following command to enable logging with JDK 11 and higher:
3838

3939
```bash
4040
java -Xms512m -Xmx1024m -XX:+UseSerialGC -Xlog:gc:file=gc.log:tags,uptime,time,level:filecount=10,filesize=16m HeapUsageExample.java
4141
```
4242

43-
Use the following command if you are using JDK8.
43+
If you are using JDK8, use the following command instead:
4444

4545
```bash
4646
java -Xms512m -Xmx1024m -XX:+UseSerialGC -Xloggc:gc.log -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation HeapUsageExample.java
4747
```
4848

49-
The `-Xms512m` and `-Xmx1024` options create a minimum and maximum heap size of 512 MiB and 1GiB respectively. This is simply so we do not have to wait for too long to see activity within the GC. Additionally, we force the JVM to use the serial garbage collector with the `-XX:+UseSerialGC` flag.
49+
The `-Xms512m` and `-Xmx1024` options create a minimum and maximum heap size of 512 MiB and 1GiB respectively. This is simply to avoid waiting too long to see activity within the GC. Additionally, you will force the JVM to use the serial garbage collector with the `-XX:+UseSerialGC` flag.
5050

51-
You will now see logs, named `gc.log.*` within the same directory. Viewing the contents you will see the following.
51+
You will now see a log file, named `gc.log` created within the same directory.
52+
53+
Open `gc.log` and the contents should look similar to:
5254

5355
```output
54-
[2024-11-08T15:04:54.304+0000][0.713s][info][gc ] GC(2) Pause Young (Allocation Failure) 139M->3M(494M) 3.627ms
56+
[2024-11-08T15:04:54.304+0000][0.713s][info][gc] GC(2) Pause Young (Allocation Failure) 139M->3M(494M) 3.627ms
5557
...
56-
[2024-11-08T15:04:54.350+0000][0.759s][info][gc ] GC(3) Pause Young (Allocation Failure) 139M->3M(494M) 3.699ms
58+
[2024-11-08T15:04:54.350+0000][0.759s][info][gc] GC(3) Pause Young (Allocation Failure) 139M->3M(494M) 3.699ms
5759
```
5860

5961
These logs provide insights into the frequency, duration, and impact of Young garbage collection events. The results may vary depending on your system.
@@ -62,11 +64,11 @@ These logs provide insights into the frequency, duration, and impact of Young ga
6264
- Pause duration: ~ 3.6 ms
6365
- Reduction size: ~ 139 MB (or 3M objects)
6466

65-
This logging method has the benefit of being verbose but at the tradeoff of clarity. Furthermore, this method clearly isn't suitable for a running process which makes debugging a live environment slightly more challenging.
67+
This logging method can be quite verbose. Also, this method isn't suitable for a running process which makes debugging a live running application slightly more challenging.
6668

6769
### Use jstat to observe real-time GC statistics
6870

69-
The following java code snippet is a long-running example that prints out a random integer and double precision floating point number 4 times a second. Copy the example below and paste into a file called `WhileLoopExample.java`.
71+
Using a file editor of your choice, copy the java code below into a file named `WhileLoopExample.java`. This java code snippet is a long-running example that prints out a random integer and double precision floating point number 4 times a second.
7072

7173
```java
7274
import java.util.Random;
@@ -100,19 +102,18 @@ public class GenerateRandom {
100102
}
101103
```
102104

103-
Run the following command and open up a separate terminal session. Start the Java program with the command below. This will use the default parameters for the garbage collection.
105+
Start the Java program with the command below. This will use the default parameters for the garbage collection:
104106

105107
```bash
106108
java WhileLoopExample.java
107109
```
108-
On the other terminal session, we use the `jstat` command to print out the JVM statistics specifically related to the GC using the `-gcutil` flag.
110+
While the program running, open another terminal session. In the new terminal use the `jstat` command to print out the JVM statistics specifically related to the GC using the `-gcutil` flag:
109111

110112
```bash
111113
jstat -gcutil $(pgrep java) 1000
112114
```
113115

114-
115-
You will obserse an output like the following until `ctl+c` is pressed.
116+
You will observe output like the following until `ctl+c` is pressed.
116117

117118
```output
118119
S0 S1 E O M CCS YGC YGCT FGC FGCT CGC CGCT GCT
Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
---
2-
title: Basic GC Tuning
2+
title: Basic GC Tuning Options
33
weight: 5
44

55
### FIXED, DO NOT MODIFY
66
layout: learningpathall
77
---
88

9-
### Update the JDK version used
9+
### Update the JDK version
1010

11-
A sensible first step is to use one of the latest long-term-support (LTS) releases of JDK. This is because the GC versions included with recent JDKs offer improvements. For example, the G1GC included with JDK11 offers improvements in the pause time compared to JDK 8. As mentioned earlier, the `java --version` command will show you the version currently in use.
11+
If you are on an older version of JDK, a sensible first step is to use one of the latest long-term-support (LTS) releases of JDK. This is because the GC versions included with recent JDKs offer improvements. For example, the G1GC included with JDK 11 offers improvements in the pause time compared to JDK 8. As shown earlier, you can use the `java --version` command to check the version currently in use.
1212

1313
```output
1414
$ java --version
@@ -20,35 +20,35 @@ OpenJDK 64-Bit Server VM Corretto-21.0.4.7.1 (build 21.0.4+7-LTS, mixed mode, sh
2020

2121
### Use an alternative GC
2222

23-
In this section we will use the `HeapUsageExample.java` file we created earlier.
23+
In this section, you will use the `HeapUsageExample.java` file you created earlier.
2424

2525
The G1 GC (Garbage-First Garbage Collector) is designed to handle large heaps and aims to provide low pause times by dividing the heap into regions and performing incremental garbage collection. This makes it suitable for applications with high allocation rates and large memory footprints.
2626

27-
We can run the following command to generate the GC logs using a different GC and compare. We have simply changed the GC from `Serial` to `G1GC` using the `-XX:+UseG1GC` option.
27+
You can run the following command to generate the GC logs using a different GC and compare. You just need to change the GC from `Serial` to `G1GC` using the `-XX:+UseG1GC` option as shown:
2828

2929
```bash
3030
java -Xms512m -Xmx1024m -XX:+UseG1GC -Xlog:gc:file=gc.log:tags,uptime,time,level:filecount=10,filesize=16m HeapUsageExample.java
3131
```
32-
From the created log file `gc.log.*`, we can observe that at a very similar time after start up (~0.75s), the Pause Young time has reduced from ~3.6ms to ~1.9ms. Further, the time between GC pauses has imprved from ~46ms to every ~98ms.
32+
From the created log file `gc.log`, you can observe that at a very similar time after start up (~0.75s), the Pause Young time reduced from ~3.6ms to ~1.9ms. Further, the time between GC pauses has improved from ~46ms to every ~98ms.
3333

3434
```output
3535
[2024-11-08T16:13:53.088+0000][0.790s][info][gc ] GC(2) Pause Young (Normal) (G1 Evacuation Pause) 307M->3M(514M) 1.976ms
3636
...
3737
[2024-11-08T16:13:53.186+0000][0.888s][info][gc ] GC(3) Pause Young (Normal) (G1 Evacuation Pause) 307M->3M(514M) 1.703ms
3838
```
39-
As discussed in the previous section, the performance improvement from moving to a G1GC will depend on the CPU overhead of your system. As such, the performance may vary depending on the cloud instance size and available CPU resources.
39+
As discussed in the previous section, the performance improvement from moving to a G1GC will depend on the CPU overhead of your system. The performance may vary depending on the cloud instance size and available CPU resources.
4040

4141
### Add GC Targets
4242

43-
You can manually provide targets for specific metrics and the GC will attempt to meet those requirements. For example, if you have a time-sensitive application such as a rest server, you may want to ensure that all customers receive a response within a specific time. You may find that if a client request is sent during GC you need to ensure that the GC pause time is minimised.
43+
You can manually provide targets for specific metrics and the GC will attempt to meet those requirements. For example, if you have a time-sensitive application such as a REST server, you may want to ensure that all customers receive a response within a specific time. You may find that if a client request is sent during GC you need to ensure that the GC pause time is minimised.
4444

45-
Running the command with the `-XX:MaxGCPauseMillis=<N>` sets a target max GC pause time.
45+
Running the command with the `-XX:MaxGCPauseMillis=<N>` sets a target max GC pause time:
4646

4747
```bash
4848
java -Xms512m -Xmx1024m -XX:+UseG1GC -XX:MaxGCPauseMillis=1 -Xlog:gc:file=gc.log:tags,uptime,time,level:filecount=10,filesize=16m HeapUsageExample.java
4949
```
5050

51-
Looking at the output below, we can see that at the same initial state after ~0.7s the pause time has been reduced. However, we can also see the initial size of the Young space has gone from 307MiB above to 124MiB. The GC decided to reduce the size of he Young space to reduce the pause time at the expense of more frequent pauses.
51+
Looking at the output below, you can see that at the same initial state after ~0.7s the pause time has reduced. However, you can also see the initial size of the Young space has gone from 307MiB above to 124MiB. The GC decided to reduce the size of the Young space to reduce the pause time at the expense of more frequent pauses.
5252

5353
```output
5454
[2024-11-08T16:27:37.061+0000][0.765s][info][gc] GC(18) Pause Young (Normal) (G1 Evacuation Pause) 124M->3M(514M) 0.489ms
@@ -60,12 +60,14 @@ Here are some additional target options you can consider to tune performance:
6060
- -XX:InitiatingHeapOccupancyPercent:
6161

6262
Defines the old generation occupancy threshold to trigger a concurrent GC cycle. Adjusting this can be beneficial if your application experiences long GC pauses due to high old generation occupancy. For example, lowering this threshold can help start GC cycles earlier, reducing the likelihood of long pauses during peak memory usage.
63+
6364
- -XX:ParallelGCThreads
6465

6566
Specifies the number of threads for parallel GC operations. Increasing this value can be beneficial for applications running on multi-core processors, as it allows GC tasks to be processed faster. For instance, a high-throughput server application might benefit from more parallel GC threads to minimize pause times and improve overall performance.
67+
6668
- -XX:G1HeapRegionSize
6769

6870
Determines the size of G1 regions, which must be a power of 2 between 1 MB and 32 MB. Adjusting this can be useful for applications with specific memory usage patterns. For example, setting a larger region size can reduce the number of regions and associated overhead for applications with large heaps, while smaller regions might be better for applications with more granular memory allocation patterns.
6971

70-
We recommend reading [this technical article](https://www.oracle.com/technical-resources/articles/java/g1gc.html) for more information of G1GC tuning.
72+
You can refer to [this technical article](https://www.oracle.com/technical-resources/articles/java/g1gc.html) for more information of G1GC tuning.
7173

content/learning-paths/servers-and-cloud-computing/java-gc-tuning/_index.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,28 @@ title: Tune the Performance of the Java Garbage Collector
33

44
minutes_to_complete: 45
55

6-
who_is_this_for: This learning path is designed for Java developers aiming to optimize application performance on Arm-based servers. It is especially valuable for those migrating applications from x86-based to Arm-based instances. Here, you'll learn about essential garbage collection (GC) tuning parameters and how to adjust them to meet your specific performance needs.
6+
who_is_this_for: This learning path is designed for Java developers aiming to optimize application performance on Arm-based servers. It is especially valuable for those migrating applications from x86-based to Arm-based instances.
77

88
learning_objectives:
99
- Understand the key differences among Java garbage collectors (GCs).
1010
- Monitor and interpret GC performance metrics.
11-
- Adjust core parameters to optimize performance for your specific workload
11+
- Adjust core parameters to optimize performance for your specific workload.
1212

1313
prerequisites:
14-
- Access to an Arm-based server
15-
- Basic understanding of Java
16-
- Java installed on your system
14+
- An Arm based instance from a cloud service provider, or an on-premise Arm server.
15+
- Basic understanding of Java and [Java installed](/install-guides/java/) on your machine.
1716

1817
author_primary: Kieran Hejmadi
1918

2019
### Tags
2120
skilllevels: Introductory
22-
subjects: Java
21+
subjects: Performance and Architecture
2322
armips:
2423
- Neoverse
2524
tools_software_languages:
2625
- Java
2726
operatingsystems:
28-
- AWS Linux
27+
- Linux
2928

3029

3130
### FIXED, DO NOT MODIFY

0 commit comments

Comments
 (0)