From c040767c49abace7c7ecb307d2c2b7d82a286889 Mon Sep 17 00:00:00 2001 From: Maddy Underwood <167196745+madeline-underwood@users.noreply.github.com> Date: Tue, 10 Dec 2024 15:53:33 +0000 Subject: [PATCH 01/11] Initial assessment. --- .../java-gc-tuning/_index.md | 11 +++--- .../java-gc-tuning/purpose_of_gc.md | 35 +++++++++++++------ 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/_index.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/_index.md index 98111756b..09a228f8c 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/_index.md @@ -3,16 +3,17 @@ title: Tune the Performance of the Java Garbage Collector minutes_to_complete: 45 -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. +who_is_this_for: This Learning Path is 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. learning_objectives: - - Understand the key differences among Java garbage collectors (GCs). - - Monitor and interpret GC performance metrics. + - Describe the key differences between differing individual Java Garbage Collectors (GCs). + - Monitor and interpret Garbage Collector performance metrics. - Adjust core parameters to optimize performance for your specific workload. prerequisites: - - An Arm based instance from a cloud service provider, or an on-premise Arm server. - - Basic understanding of Java and [Java installed](/install-guides/java/) on your machine. + - An Arm-based instance from a cloud service provider, or an on-premise Arm server. + - Basic understanding of Java. + - An [installation of Java](/install-guides/java/) on your machine. author_primary: Kieran Hejmadi diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/purpose_of_gc.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/purpose_of_gc.md index ef8bb2e12..a81bb9a38 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/purpose_of_gc.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/purpose_of_gc.md @@ -1,24 +1,37 @@ --- -title: Purpose of GC +title: The Purpose of Garbage Collector weight: 2 ### FIXED, DO NOT MODIFY layout: learningpathall --- -### The Purpose of GC +### Purpose and Setup -Garbage collection (GC) is the term used for automatic memory management primarily within managed langauages such as Java. This means developers do not need to explicitly free variables once they're no longer required, such as in the C programming language. Java Virtual Machine distributions typically come with several GCs. The disadvantage is that Java has less control of memory growth which can cause knock-on effects such as page faults. Further, the automatic process of finding variables whose memory can be freed occurs CPU overhead that may run intermittently such as in the GC mark-swap algorithm. The execution of your Java application may pause during this time, controlling the length and frequency of these pauses can greatly improve performance. +Garbage Collection (GC) is the term for automatic memory management, primarily used within managed langauages such as Java. -Broadly speaking, the GC has to do 3 main tasks; find the objects to free, free the memory and compact the heap. Most GCs further separate the heap into generations. -- **The young generation** holds data that is used for a short period. -- **The old generation** holds longer-lived data. +Automatic memory management means that developers do not need to explicitly free variables once they are no longer required, such as in the C programming language. -This takes advantage of the fact that most data is short lived so it's faster to process just the young generation during GC, resulting in shorted pause times. A full GC refers to going through the entire heap, leading to the so called 'stop-the-world pauses' that impact your applications performance. +Java Virtual Machine distributions typically come with several Garbage Collectors. The disadvantage is this is that Java has less control of memory growth which can cause knock-on effects such as page faults. In addition, the automatic process of finding variables whose memory can be freed occurs CPU overhead that may run intermittently such as in the GC mark-swap algorithm. The execution of your Java application might pause during this time, controlling the length and frequency of these pauses can greatly improve performance. + +Broadly speaking, the Garbage Collector must perform three main tasks: + +* Find the objects to free. +* Free the memory. +* Compact the heap. + +Most GCs further separate the heap into generations: + +* The young generation holds data that is used for a short period. +* The old generation holds longer-lived data. + +This takes advantage of the fact that most data is short-lived so it is faster to process just the young generation during GC, resulting in shorted pause times. A full GC refers to going through the entire heap, leading to the so called 'stop-the-world pauses' that impact the performance of your application. ### Check the JDK version -Different versions of the Java Development Kit (JDK) ship with different GCs. First, check the version of Java installed on your system by running the following command: +Different versions of the Java Development Kit (JDK) ship with different Garbage Collectors. + +First, check the version of Java installed on your system by running the following command: ```bash java --version @@ -36,13 +49,13 @@ If the `java` command is not recognised, please follow the [Arm Java install gui ### Check which GCs are available -Next, you want to understand which standard GCs are available to use. Run the following command to print the available GCs: +To find out the range of standard GCs that are available for you to use, run the following command which will print the information: ```bash java -XX:+PrintFlagsFinal -version | egrep 'Use\w+GC' ``` -The output below shows that 5 GCs are available to use. The middle column shows the default value. Here you can see that the `G1GC` GC is enabled. +The output below shows that five GCs are available to use. The middle column shows the default value. Here you can see that the `G1GC` GC is enabled. ```output bool UseAdaptiveSizeDecayMajorGCCost = true {product} {default} @@ -57,4 +70,4 @@ The output below shows that 5 GCs are available to use. The middle column shows ``` -In the next section you will learn about the different types of GCs. +In the next section, you will learn about the different types of GCs. From 1844073a4d5e6363bc4889058cf0d009b2d33167 Mon Sep 17 00:00:00 2001 From: Maddy Underwood <167196745+madeline-underwood@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:07:53 +0000 Subject: [PATCH 02/11] Rephrasing, clarifying, restructuring. --- .../java-gc-tuning/_index.md | 2 +- .../java-gc-tuning/different_gcs.md | 2 +- .../java-gc-tuning/purpose_of_gc.md | 24 +++++++++++-------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/_index.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/_index.md index 09a228f8c..25b1d627d 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/_index.md @@ -6,7 +6,7 @@ minutes_to_complete: 45 who_is_this_for: This Learning Path is 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. learning_objectives: - - Describe the key differences between differing individual Java Garbage Collectors (GCs). + - Describe the key differences between individual Java Garbage Collectors (GCs). - Monitor and interpret Garbage Collector performance metrics. - Adjust core parameters to optimize performance for your specific workload. diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md index dc26e4c2f..1aba0f397 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md @@ -1,5 +1,5 @@ --- -title: Types of GCs +title: Types of Garbage Collectors weight: 3 ### FIXED, DO NOT MODIFY diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/purpose_of_gc.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/purpose_of_gc.md index a81bb9a38..a928f56ba 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/purpose_of_gc.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/purpose_of_gc.md @@ -1,31 +1,35 @@ --- -title: The Purpose of Garbage Collector +title: Overview weight: 2 ### FIXED, DO NOT MODIFY layout: learningpathall --- -### Purpose and Setup +### Automatic Memory Management -Garbage Collection (GC) is the term for automatic memory management, primarily used within managed langauages such as Java. +Garbage Collection (GC) is the term used in programming to describe automatic memory management, primarily deployed within managed langauages such as Java. -Automatic memory management means that developers do not need to explicitly free variables once they are no longer required, such as in the C programming language. +In a programming language such as C, developers need to explicitly free variables once they are no longer required. Automatic memory management means that this is not necessary which removes the potential for human error. -Java Virtual Machine distributions typically come with several Garbage Collectors. The disadvantage is this is that Java has less control of memory growth which can cause knock-on effects such as page faults. In addition, the automatic process of finding variables whose memory can be freed occurs CPU overhead that may run intermittently such as in the GC mark-swap algorithm. The execution of your Java application might pause during this time, controlling the length and frequency of these pauses can greatly improve performance. - -Broadly speaking, the Garbage Collector must perform three main tasks: +Generally, the Garbage Collector must perform three main tasks: * Find the objects to free. * Free the memory. -* Compact the heap. +* Compact the heap. + +Java Virtual Machine distributions typically come with several Garbage Collectors, which has the disadvantage that subsequently Java has less control of memory growth which can cause knock-on effects such as page faults. In addition, the automatic process of finding variables with memory can be freed creates CPU overhead, such as during the GC mark-swap algorithm. The execution of a Java application might pause during this process, and so being able to control the length and frequency of these pauses can greatly improve performance. -Most GCs further separate the heap into generations: +### Garbage Collection Generations + +Most GCs further separate the heap of the memory into generations: * The young generation holds data that is used for a short period. * The old generation holds longer-lived data. -This takes advantage of the fact that most data is short-lived so it is faster to process just the young generation during GC, resulting in shorted pause times. A full GC refers to going through the entire heap, leading to the so called 'stop-the-world pauses' that impact the performance of your application. +This takes advantage of the fact that most data is short-lived so it is faster to process just the young generation during GC, resulting in shorted pause times. + +A full GC refers to going through the entire heap, leading to the so called 'stop-the-world pauses' that impact the performance of your application. ### Check the JDK version From 5de8738d2e9fde81e8d1384d7055c33955258d87 Mon Sep 17 00:00:00 2001 From: Maddy Underwood <167196745+madeline-underwood@users.noreply.github.com> Date: Wed, 11 Dec 2024 12:08:35 +0000 Subject: [PATCH 03/11] Further refinements. New section to segment content to improve readability. --- .../java-gc-tuning/Example_application.md | 2 +- .../java-gc-tuning/Tuning Parameters.md | 2 +- .../java-gc-tuning/_index.md | 2 +- .../java-gc-tuning/different_gcs.md | 10 ++-- .../java-gc-tuning/purpose_of_gc.md | 55 ++----------------- .../java-gc-tuning/setup.md | 51 +++++++++++++++++ 6 files changed, 65 insertions(+), 57 deletions(-) create mode 100644 content/learning-paths/servers-and-cloud-computing/java-gc-tuning/setup.md diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Example_application.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Example_application.md index 9b0d4664e..7761831e6 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Example_application.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Example_application.md @@ -1,6 +1,6 @@ --- title: Example Application -weight: 4 +weight: 5 ### FIXED, DO NOT MODIFY layout: learningpathall diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Tuning Parameters.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Tuning Parameters.md index 0de271795..b25ec4de6 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Tuning Parameters.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Tuning Parameters.md @@ -1,6 +1,6 @@ --- title: Basic GC Tuning Options -weight: 5 +weight: 6 ### FIXED, DO NOT MODIFY layout: learningpathall diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/_index.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/_index.md index 25b1d627d..59701ecba 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/_index.md @@ -3,7 +3,7 @@ title: Tune the Performance of the Java Garbage Collector minutes_to_complete: 45 -who_is_this_for: This Learning Path is 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. +who_is_this_for: This Learning Path is for Java developers aiming to optimize application performance on Arm-based servers, especially those migrating applications from x86-based to Arm-based instances. learning_objectives: - Describe the key differences between individual Java Garbage Collectors (GCs). diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md index 1aba0f397..206a10e14 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md @@ -1,22 +1,22 @@ --- -title: Types of Garbage Collectors -weight: 3 +title: Types of Garbage Collector +weight: 4 ### FIXED, DO NOT MODIFY layout: learningpathall --- -In this section, you will explore the key differences among commonly used production GCs. You will learn about the advantages and disadvantages of each GC, along with guidance on selecting the best one for your Java application. +In this section, you will explore the key differences among commonly-used production GCs. You will learn about the advantages and disadvantages of each GC, along with guidance on selecting the best one for your Java application. ### Serial Garbage Collector -The Serial Garbage Collector (Serial GC) is a simple, single-threaded garbage collector, primarily designed for small applications or single-processor environments. Java’s heap is divided into two main regions, or generations—the young generation and the old generation—to help manage short-lived and long-lived objects differently. In the Serial GC, both the young and old generations are collected using a single-threaded, “stop-the-world” approach, where all application threads pause during garbage collection. This design can lead to noticeable application pauses, particularly as the heap size grows, making the Serial GC unsuitable for larger, latency-sensitive applications. +The Serial Garbage Collector (Serial GC) is a simple, single-threaded garbage collector, primarily designed for small applications or single-processor environments. As described earlier, Java’s heap is divided into two main generations, the new generation, to manage short-lived objects, and the old generation, to manage long-lived objects. In the Serial Garbage Collector, both the young and old generations are collected using a single-threaded, “stop-the-world” approach, where all application threads pause during garbage collection. This design can lead to noticeable application pauses, particularly as the heap size grows, making the Serial GC unsuitable for larger, latency-sensitive applications. In production deployments, the Serial GC is rarely used in high-throughput or multi-threaded applications because it does not utilize the parallel processing capabilities of modern CPUs, resulting in longer pause times compared to other collectors. Its limitations make it inefficient for large-scale applications, where even brief pauses can disrupt user experience. However, for applications with limited memory and CPU resources or those needing a predictable, single-threaded execution model, the Serial GC remains a straightforward and low-overhead option. ### Throughput Garbage Collector -The Parallel GC, also called the Throughput GC, uses the same generational heap structure as the Serial GC, dividing memory into young and old generations to manage short-lived and long-lived objects. Unlike the Serial GC, the Parallel GC uses multiple threads for garbage collection, improving efficiency on larger heaps. When the young generation fills up, a young collection pause occurs, briefly pausing application threads to clear the young space. As shown in the diagram below, data in the young generation space is mostly freed, with surviving objects moved to the old generation. +The Parallel Garbage Collector, also called the Throughput Garbage Collector, uses the same generational heap structure as the Serial Garbage Collector, dividing memory into young and old generations to manage short-lived and long-lived objects. Unlike the Serial GC however, the Parallel GC uses multiple threads for Garbage Collection, which improves efficiency on larger heaps. When the young generation fills up, a young collection pause occurs, briefly pausing application threads to clear the young space. As shown in the diagram below, data in the young generation space is mostly freed, with surviving objects moved to the old generation. Once the old generation is full, a full GC pause blocks all application threads for a longer duration to clean both generations. These full GC pauses can degrade performance in latency-sensitive applications, such as database management systems, where interruptions affect responsiveness. The Parallel GC’s multi-threaded approach helps reduce pause times, making it better suited for applications that prioritize throughput and can handle occasional longer pauses for full collection. diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/purpose_of_gc.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/purpose_of_gc.md index a928f56ba..3ee92f9c1 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/purpose_of_gc.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/purpose_of_gc.md @@ -8,9 +8,9 @@ layout: learningpathall ### Automatic Memory Management -Garbage Collection (GC) is the term used in programming to describe automatic memory management, primarily deployed within managed langauages such as Java. +Garbage Collection (GC) is the term used in programming to describe the concept and process of automatic memory management, primarily deployed within managed languages such as Java. -In a programming language such as C, developers need to explicitly free variables once they are no longer required. Automatic memory management means that this is not necessary which removes the potential for human error. +In a programming language such as C, developers need to explicitly free variables once they are no longer required. Automatic memory management removes the requirement for this procedure, meaning that there is less potential for human error. Generally, the Garbage Collector must perform three main tasks: @@ -18,60 +18,17 @@ Generally, the Garbage Collector must perform three main tasks: * Free the memory. * Compact the heap. -Java Virtual Machine distributions typically come with several Garbage Collectors, which has the disadvantage that subsequently Java has less control of memory growth which can cause knock-on effects such as page faults. In addition, the automatic process of finding variables with memory can be freed creates CPU overhead, such as during the GC mark-swap algorithm. The execution of a Java application might pause during this process, and so being able to control the length and frequency of these pauses can greatly improve performance. +Java Virtual Machine distributions typically come with several Garbage Collectors, which can have the disadvantage that Java has less control of memory growth. This can subsequently cause knock-on effects such as page faults. In addition, the automatic process of finding variables with memory that can be freed creates CPU overhead, occurring during times such as the GC mark-swap algorithm. The execution of a Java application might pause during this process, and so being able to control the length and frequency of these pauses is key to optimizing performance. ### Garbage Collection Generations -Most GCs further separate the heap of the memory into generations: +Most Garbage Collectors separate the heap of the memory into generations: * The young generation holds data that is used for a short period. * The old generation holds longer-lived data. -This takes advantage of the fact that most data is short-lived so it is faster to process just the young generation during GC, resulting in shorted pause times. +By doing this there are shorter pause times, as most data is short-lived and is faster to process. -A full GC refers to going through the entire heap, leading to the so called 'stop-the-world pauses' that impact the performance of your application. +A full Garbage Collections means going through the entire heap, leading to 'stop-the-world' pauses that impact the performance of an application. -### Check the JDK version -Different versions of the Java Development Kit (JDK) ship with different Garbage Collectors. - -First, check the version of Java installed on your system by running the following command: - -```bash -java --version -``` - -The output should look similar to: - -```output -openjdk 21.0.4 2024-07-16 LTS -OpenJDK Runtime Environment Corretto-21.0.4.7.1 (build 21.0.4+7-LTS) -OpenJDK 64-Bit Server VM Corretto-21.0.4.7.1 (build 21.0.4+7-LTS, mixed mode, sharing) -``` - -If the `java` command is not recognised, please follow the [Arm Java install guide](/install-guides/java/) to install Java on your system. - -### Check which GCs are available - -To find out the range of standard GCs that are available for you to use, run the following command which will print the information: - -```bash -java -XX:+PrintFlagsFinal -version | egrep 'Use\w+GC' -``` - -The output below shows that five GCs are available to use. The middle column shows the default value. Here you can see that the `G1GC` GC is enabled. - -```output - bool UseAdaptiveSizeDecayMajorGCCost = true {product} {default} - bool UseAdaptiveSizePolicyWithSystemGC = false {product} {default} - bool UseDynamicNumberOfGCThreads = true {product} {default} - bool UseG1GC = true {product} {ergonomic} - bool UseMaximumCompactionOnSystemGC = true {product} {default} - bool UseParallelGC = false {product} {default} - bool UseSerialGC = false {product} {default} - bool UseShenandoahGC = false {product} {default} - bool UseZGC = false {product} {default} - -``` - -In the next section, you will learn about the different types of GCs. diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/setup.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/setup.md new file mode 100644 index 000000000..61f9e531e --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/setup.md @@ -0,0 +1,51 @@ +--- +title: Setup +weight: 3 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- +### Check the JDK version + +Different versions of the Java Development Kit (JDK) ship with different Garbage Collectors. + +To check the version of Java installed on your system, run the following command: + +```bash +java --version +``` + +The output should look similar to: + +```output +openjdk 21.0.4 2024-07-16 LTS +OpenJDK Runtime Environment Corretto-21.0.4.7.1 (build 21.0.4+7-LTS) +OpenJDK 64-Bit Server VM Corretto-21.0.4.7.1 (build 21.0.4+7-LTS, mixed mode, sharing) +``` + +If the `java` command is not recognised, you can follow the [Arm Java install guide](/install-guides/java/) to install Java on your system. + +### Identify available Garbage Collectors + +To find out the range of standard Garbage Collectors that are available for you to use, run the following command which prints the information: + +```bash +java -XX:+PrintFlagsFinal -version | egrep 'Use\w+GC' +``` + +The example output below shows that five GCs are available to use. The middle column shows the default value. Here you can see that the `G1GC` GC is enabled: + +```output + bool UseAdaptiveSizeDecayMajorGCCost = true {product} {default} + bool UseAdaptiveSizePolicyWithSystemGC = false {product} {default} + bool UseDynamicNumberOfGCThreads = true {product} {default} + bool UseG1GC = true {product} {ergonomic} + bool UseMaximumCompactionOnSystemGC = true {product} {default} + bool UseParallelGC = false {product} {default} + bool UseSerialGC = false {product} {default} + bool UseShenandoahGC = false {product} {default} + bool UseZGC = false {product} {default} + +``` + +In the next section, you will learn about the different types of GCs. From bf967eb2eb2bbce795d2e624b7938176eda7f6b4 Mon Sep 17 00:00:00 2001 From: Maddy Underwood <167196745+madeline-underwood@users.noreply.github.com> Date: Wed, 11 Dec 2024 12:39:16 +0000 Subject: [PATCH 04/11] Added Figure labels to diagrams, and centre-aligned. --- .../java-gc-tuning/different_gcs.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md index 206a10e14..58e44b979 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md @@ -16,11 +16,11 @@ In production deployments, the Serial GC is rarely used in high-throughput or mu ### Throughput Garbage Collector -The Parallel Garbage Collector, also called the Throughput Garbage Collector, uses the same generational heap structure as the Serial Garbage Collector, dividing memory into young and old generations to manage short-lived and long-lived objects. Unlike the Serial GC however, the Parallel GC uses multiple threads for Garbage Collection, which improves efficiency on larger heaps. When the young generation fills up, a young collection pause occurs, briefly pausing application threads to clear the young space. As shown in the diagram below, data in the young generation space is mostly freed, with surviving objects moved to the old generation. +The Parallel Garbage Collector, also called the Throughput Garbage Collector, uses the same generational heap structure as the Serial Garbage Collector, dividing memory into young and old generations to manage short-lived and long-lived objects. Unlike the Serial GC however, the Parallel GC uses multiple threads for Garbage Collection, which improves efficiency on larger heaps. When the young generation fills up, a young collection pause occurs, briefly pausing application threads to clear the young space. As shown in Figure 1, data in the young generation space is mostly freed, with surviving objects moved to the old generation. Once the old generation is full, a full GC pause blocks all application threads for a longer duration to clean both generations. These full GC pauses can degrade performance in latency-sensitive applications, such as database management systems, where interruptions affect responsiveness. The Parallel GC’s multi-threaded approach helps reduce pause times, making it better suited for applications that prioritize throughput and can handle occasional longer pauses for full collection. -![throughput_minor_gc](./throughput_gc.jpg) +![throughput_minor_gc alt-text#center]( ./throughput_gc.jpg "Figure 1: Throughput Garbage Collector") ### Garbage First Garbage Collector (G1GC) @@ -28,7 +28,7 @@ The G1GC is the default garbage collector starting from JDK version 11. G1 Garba Although collecting a region still necessitates pausing application threads, G1GC can prioritize regions with the most garbage, thereby minimizing the time spent on garbage collection. The result is that the pause times for full GC pauses is less compared to the throughput collector. The diagram below illustrates how the G1GC is divided into discrete chunks and how memory is freed. -![g1gc](./g1gc.jpg) +![g1gc alt-text#center](./g1gc.jpg "Figure 2: Garbage First Garbage Collector") ### ZGC and Shenandoah GC @@ -40,7 +40,7 @@ However, the tradeoff with these collectors is a higher CPU overhead, as concurr ### Comparison Table -The following table can be used as a rough guide for your specific java application. +The following table can be used as an approximate guide for your specific java application. From 9bbf31c49cbc8ae9865947c26a2aca08503b6d77 Mon Sep 17 00:00:00 2001 From: Maddy Underwood <167196745+madeline-underwood@users.noreply.github.com> Date: Wed, 11 Dec 2024 13:32:04 +0000 Subject: [PATCH 05/11] Further cleanup. --- .../java-gc-tuning/Example_application.md | 40 ++++++++++++------- .../java-gc-tuning/Tuning Parameters.md | 28 +++++++------ .../java-gc-tuning/different_gcs.md | 22 +++++----- .../java-gc-tuning/optional_tuning.md | 2 +- 4 files changed, 54 insertions(+), 38 deletions(-) diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Example_application.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Example_application.md index 7761831e6..fd57cce6c 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Example_application.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Example_application.md @@ -6,9 +6,11 @@ weight: 5 layout: learningpathall --- -## Example Application. +## Example Application -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. +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. ```java public class HeapUsageExample { @@ -32,9 +34,13 @@ public class HeapUsageExample { } ``` -### Enable GC logging +### Enable Garbage Collector logging + +To observe what the Garbage Collector 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 might be rewritten and lost. -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: +Run the following command to enable logging with JDK 11 and higher: ```bash java -Xms512m -Xmx1024m -XX:+UseSerialGC -Xlog:gc:file=gc.log:tags,uptime,time,level:filecount=10,filesize=16m HeapUsageExample.java @@ -46,7 +52,7 @@ If you are using JDK8, use the following command instead: java -Xms512m -Xmx1024m -XX:+UseSerialGC -Xloggc:gc.log -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation HeapUsageExample.java ``` -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. +The `-Xms512m` and `-Xmx1024` options create a minimum and maximum heap size of 512 MiB and 1GiB respectively. This is to avoid waiting too long to see activity within the GC. Additionally, you can force the JVM to use the serial garbage collector with the `-XX:+UseSerialGC` flag. You will now see a log file, named `gc.log` created within the same directory. @@ -58,17 +64,19 @@ Open `gc.log` and the contents should look similar to: [2024-11-08T15:04:54.350+0000][0.759s][info][gc] GC(3) Pause Young (Allocation Failure) 139M->3M(494M) 3.699ms ``` -These logs provide insights into the frequency, duration, and impact of Young garbage collection events. The results may vary depending on your system. +These logs provide insights into the frequency, duration, and impact of Young garbage collection events. The results can vary depending on your system. - Frequency: ~ every 46 ms - Pause duration: ~ 3.6 ms - Reduction size: ~ 139 MB (or 3M objects) -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. +This logging method can be quite verbose, and makes it challenging to debug a live running application. ### Use jstat to observe real-time GC statistics -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. +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 four times a second: ```java import java.util.Random; @@ -107,13 +115,15 @@ Start the Java program with the command below. This will use the default paramet ```bash java WhileLoopExample.java ``` -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: +While the program is 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: ```bash jstat -gcutil $(pgrep java) 1000 ``` -You will observe output like the following until `ctl+c` is pressed. +You will observe output like the following until `ctl+c` is pressed: ```output S0 S1 E O M CCS YGC YGCT FGC FGCT CGC CGCT GCT @@ -125,10 +135,10 @@ You will observe output like the following until `ctl+c` is pressed. ``` The columns of interest are: -- **E (Eden Space Utilization)**: The percentage of the Eden space that is currently used. High utilization indicates frequent allocations and can trigger minor GCs. -- **O (Old Generation Utilization)**: The percentage of the Old (Tenured) generation that is currently used. High utilization can lead to Full GCs, which are more expensive. -- **YGCT (Young Generation GC Time)**: The total time (in seconds) spent in Young Generation (minor) GC events. High values indicate frequent minor GCs, which can impact performance. -- **FGCT (Full GC Time)**: The total time (in seconds) spent in Full GC events. High values indicate frequent Full GCs, which can significantly impact performance. -- **GCT (Total GC Time)**: The total time (in seconds) spent in all GC events (Young, Full, and Concurrent). This provides an overall view of the time spent in GC, helping to assess the impact on application performance. +- **E (Eden Space Utilization)**: The percentage of the Eden space that is being used. High utilization indicates frequent allocations and can trigger minor GCs. +- **O (Old Generation Utilization)**: The percentage of the Old (Tenured) generation that is being used. High utilization can lead to Full GCs, which are more expensive. +- **YGCT (Young Generation GC Time)**: The total time in seconds spent in Young Generation (minor) GC events. High values indicate frequent minor GCs, which can impact performance. +- **FGCT (Full GC Time)**: The total time in seconds spent in Full GC events. High values indicate frequent Full GCs, which can significantly impact performance. +- **GCT (Total GC Time)**: The total time in seconds spent in all GC events (Young, Full, and Concurrent). This provides an overall view of the time spent in GC, helping to assess the impact on application performance. diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Tuning Parameters.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Tuning Parameters.md index b25ec4de6..2f95f6f03 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Tuning Parameters.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Tuning Parameters.md @@ -8,7 +8,9 @@ layout: learningpathall ### Update the JDK version -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. +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 on previous releases. 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: ```output $ java --version @@ -22,25 +24,27 @@ OpenJDK 64-Bit Server VM Corretto-21.0.4.7.1 (build 21.0.4+7-LTS, mixed mode, sh In this section, you will use the `HeapUsageExample.java` file you created earlier. -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. +The Garbage-First Garbage Collector (G1GC) 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. + +You can run the following command to generate the GC logs using a different GC and compare the two. -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: +To make this comparison, change the Garbage Collector from `Serial` to `G1GC` using the `-XX:+UseG1GC` option: ```bash java -Xms512m -Xmx1024m -XX:+UseG1GC -Xlog:gc:file=gc.log:tags,uptime,time,level:filecount=10,filesize=16m HeapUsageExample.java ``` -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. +From the created log file `gc.log`, you can see that at a 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. ```output [2024-11-08T16:13:53.088+0000][0.790s][info][gc ] GC(2) Pause Young (Normal) (G1 Evacuation Pause) 307M->3M(514M) 1.976ms ... [2024-11-08T16:13:53.186+0000][0.888s][info][gc ] GC(3) Pause Young (Normal) (G1 Evacuation Pause) 307M->3M(514M) 1.703ms ``` -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. +As described in the previous section, the performance improvement from moving to a G1GC depends on the CPU overhead of your system. The performance can vary depending on the cloud instance size and available CPU resources. -### Add GC Targets +### Add Garbage Collector Targets -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. +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 might want to ensure that all customers receive a response within a specific time. You might find that if a client request is sent during Garbage Collection that you need to ensure that the GC pause time is minimised. Running the command with the `-XX:MaxGCPauseMillis=` sets a target max GC pause time: @@ -55,19 +59,19 @@ Looking at the output below, you can see that at the same initial state after ~0 [2024-11-08T16:27:37.149+0000][0.853s][info][gc] GC(19) Pause Young (Normal) (G1 Evacuation Pause) 193M->3M(514M) 0.482ms ``` -Here are some additional target options you can consider to tune performance: +Here are some additional target options that you can consider to tune performance: - -XX:InitiatingHeapOccupancyPercent: -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. +This defines the old generation occupancy threshold to trigger a concurrent GC cycle. Adjusting this is 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. - -XX:ParallelGCThreads -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. +This specifies the number of threads for parallel GC operations. Increasing this value is 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. - -XX:G1HeapRegionSize -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. +This 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. -You can refer to [this technical article](https://www.oracle.com/technical-resources/articles/java/g1gc.html) for more information of G1GC tuning. +See [this technical article](https://www.oracle.com/technical-resources/articles/java/g1gc.html) for more information of G1GC tuning. diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md index 58e44b979..1d4a29813 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md @@ -10,37 +10,39 @@ In this section, you will explore the key differences among commonly-used produc ### Serial Garbage Collector -The Serial Garbage Collector (Serial GC) is a simple, single-threaded garbage collector, primarily designed for small applications or single-processor environments. As described earlier, Java’s heap is divided into two main generations, the new generation, to manage short-lived objects, and the old generation, to manage long-lived objects. In the Serial Garbage Collector, both the young and old generations are collected using a single-threaded, “stop-the-world” approach, where all application threads pause during garbage collection. This design can lead to noticeable application pauses, particularly as the heap size grows, making the Serial GC unsuitable for larger, latency-sensitive applications. +The Serial Garbage Collector (Serial GC) is a simple, single-threaded garbage collector, primarily designed for small applications or single-processor environments. As described earlier, Java’s heap is divided into two main generations, the new generation, to manage short-lived objects, and the old generation, to manage long-lived objects. -In production deployments, the Serial GC is rarely used in high-throughput or multi-threaded applications because it does not utilize the parallel processing capabilities of modern CPUs, resulting in longer pause times compared to other collectors. Its limitations make it inefficient for large-scale applications, where even brief pauses can disrupt user experience. However, for applications with limited memory and CPU resources or those needing a predictable, single-threaded execution model, the Serial GC remains a straightforward and low-overhead option. +In the Serial Garbage Collector, both the young and old generations are collected using a single-threaded, “stop-the-world” approach, where all application threads pause during garbage collection. This design can lead to noticeable application pauses, particularly as the heap size grows, making the Serial GC unsuitable for larger, latency-sensitive applications. + +In production deployments, the Serial GC is rarely used in high-throughput or multi-threaded applications as it does not utilize the parallel processing capabilities of modern CPUs, and so has longer pause times compared to other collectors. These limitations make it inefficient for large-scale applications, where even brief pauses can disrupt user experience. However, for applications with limited memory and CPU resources, or those needing a predictable, single-threaded execution model, the Serial GC remains a straightforward and low-overhead option. ### Throughput Garbage Collector The Parallel Garbage Collector, also called the Throughput Garbage Collector, uses the same generational heap structure as the Serial Garbage Collector, dividing memory into young and old generations to manage short-lived and long-lived objects. Unlike the Serial GC however, the Parallel GC uses multiple threads for Garbage Collection, which improves efficiency on larger heaps. When the young generation fills up, a young collection pause occurs, briefly pausing application threads to clear the young space. As shown in Figure 1, data in the young generation space is mostly freed, with surviving objects moved to the old generation. -Once the old generation is full, a full GC pause blocks all application threads for a longer duration to clean both generations. These full GC pauses can degrade performance in latency-sensitive applications, such as database management systems, where interruptions affect responsiveness. The Parallel GC’s multi-threaded approach helps reduce pause times, making it better suited for applications that prioritize throughput and can handle occasional longer pauses for full collection. +Once the old generation is full, a full GC pause blocks all application threads for a longer duration to clean both generations. These full GC pauses can degrade performance in latency-sensitive applications, such as database management systems, where interruptions affect responsiveness. The Parallel GC’s multi-threaded approach helps reduce pause times, making it better-suited to applications that prioritize throughput and can handle occasional longer pauses for full collection. ![throughput_minor_gc alt-text#center]( ./throughput_gc.jpg "Figure 1: Throughput Garbage Collector") ### Garbage First Garbage Collector (G1GC) -The G1GC is the default garbage collector starting from JDK version 11. G1 Garbage Collector (GC) works by dividing the heap into discrete regions, typically around 2,048 by default. These regions can be part of either the old or new generation and do not need to be contiguous. The purpose of having regions in the old generation is to allow concurrent background threads to identify and target regions with a higher concentration of unreferenced objects. The tradeoff of using concurrent threads is at the expense of slightly higher CPU utilisation. G1GC is most effective when there is at least ~20% unutilised CPU headroom. +From JDK Version 11, the G1GC is the default Garbage Collector. G1 Garbage Collector (GC) works by dividing the heap into discrete regions, typically around 2,048 by default. These regions can be part of either the old or new generation and do not need to be contiguous. The purpose of having regions in the old generation is to allow concurrent background threads to identify and target regions with a higher concentration of unreferenced objects. The trade-off of using concurrent threads is at the expense of slightly higher CPU utilisation. G1GC is most effective when there is at least 20% unutilised CPU headroom. -Although collecting a region still necessitates pausing application threads, G1GC can prioritize regions with the most garbage, thereby minimizing the time spent on garbage collection. The result is that the pause times for full GC pauses is less compared to the throughput collector. The diagram below illustrates how the G1GC is divided into discrete chunks and how memory is freed. +Although collecting a region still necessitates pausing application threads, G1GC can prioritize regions with the most garbage, thereby minimizing the time spent on garbage collection. The result is that the pause times for full GC pauses is less compared to the throughput collector. Figure 2 illustrates how the G1GC is divided into discrete chunks and how memory is freed. ![g1gc alt-text#center](./g1gc.jpg "Figure 2: Garbage First Garbage Collector") -### ZGC and Shenandoah GC +### ZGC and Shenandoah Garbage Collectors -Heap compaction time in Java garbage collection refers to the process of reorganizing live objects in memory to eliminate fragmentation. In the G1GC, heap compaction time is largely determined by the time spent relocating objects within memory, which requires pausing all application threads during the process. In contrast, the ZGC and Shenandoah GC can perform heap compaction concurrently while the application continues running, reducing pause times. ZGC and Shenandoah GCs use a form of locking to implement concurrent heap compaction in a light-weight manner. Starting from JDK version 15, ZGC became production ready. +Heap compaction time in Java Garbage Collection refers to the process of reorganizing live objects in memory to eliminate fragmentation. In the G1GC, heap compaction time is largely determined by the time spent relocating objects within memory, which requires pausing all application threads during the process. In contrast, the ZGC and Shenandoah Garbage Collectors can perform heap compaction concurrently while the application continues running, reducing pause times. ZGC and Shenandoah GCs use a form of locking to implement concurrent heap compaction in a lightweight manner. Starting from JDK version 15, ZGC became production-ready. -The ZGC and Shenandoah GC are particularly suited for applications that require ultra-low pause times and can benefit from concurrent garbage collection, making them ideal for large-scale, latency-sensitive applications like real-time analytics, trading systems, and other interactive services. By allowing heap compaction to occur concurrently, these collectors significantly reduce application pauses compared to G1GC, which pauses all threads during compaction. +The ZGC and Shenandoah Garbage Collectors are particularly suited for applications that require ultra-low pause times and can benefit from concurrent garbage collection, making them ideal for large-scale, latency-sensitive applications such as real-time analytics, trading systems, and other interactive services. By allowing heap compaction to occur concurrently, these collectors significantly reduce application pauses compared to G1GC, which pauses all threads during compaction. -However, the tradeoff with these collectors is a higher CPU overhead, as concurrent garbage collection requires additional processing while the application is running. +However, the trade-off with these collectors is a higher CPU overhead, as concurrent garbage collection requires additional processing while the application is running. ### Comparison Table -The following table can be used as an approximate guide for your specific java application. +You can use the following table as an approximate guide for your specific java application. diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md index f5acbdc5e..cb34badd1 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md @@ -8,7 +8,7 @@ layout: learningpathall ## Optional Tuning Parameters -If you have an intermediate understanding of Java performance, you can experiment with the additional tuning options in this section to see how it impacts your applications performance. This is a non-exhaustive list. Please see the 'Next Steps' tab for further reading. +If you have an intermediate understanding of Java performance, you can experiment with the additional tuning options in this section to see how it impacts the performance of your application. This is a non-exhaustive list. Please see the 'Next Steps' tab for further reading. ### Which adaptive heap sizing strategy is being used? From b930bf98344caf5ee2da333833eca92704600f6b Mon Sep 17 00:00:00 2001 From: Maddy Underwood <167196745+madeline-underwood@users.noreply.github.com> Date: Wed, 11 Dec 2024 13:51:57 +0000 Subject: [PATCH 06/11] Spelling, grammar, remove figurative language. --- .../java-gc-tuning/Tuning Parameters.md | 2 +- .../java-gc-tuning/optional_tuning.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Tuning Parameters.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Tuning Parameters.md index 2f95f6f03..5ce22b4e9 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Tuning Parameters.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Tuning Parameters.md @@ -33,7 +33,7 @@ To make this comparison, change the Garbage Collector from `Serial` to `G1GC` us ```bash java -Xms512m -Xmx1024m -XX:+UseG1GC -Xlog:gc:file=gc.log:tags,uptime,time,level:filecount=10,filesize=16m HeapUsageExample.java ``` -From the created log file `gc.log`, you can see that at a 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. +From the created log file `gc.log`, you can see that at a similar time after startup (~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. ```output [2024-11-08T16:13:53.088+0000][0.790s][info][gc ] GC(2) Pause Young (Normal) (G1 Evacuation Pause) 307M->3M(514M) 1.976ms diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md index cb34badd1..b2974ab05 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md @@ -24,9 +24,9 @@ In JDK8, to observe how the JVM is resizing an application, set the `-XX:+PrintA ### Is your GC NUMA aware? -Non-uniform memory architecture(NUMA) occurs when the memory performance varies depending on which core the application is running on and where the data is in memory. This is a common occurence if you are using a system with multiple sockets. If your system has multiple sockets you need to ensure the GC is aware of this to optimise memory access patterns. The `numactl` command line tool can be used to check if your system is of non-uniform memory architecture. +Non-uniform memory architecture(NUMA) occurs when the memory performance varies depending on which core the application is running on and where the data is in memory. This is a common occurrence if you are using a system with multiple sockets. If your system has multiple sockets you need to ensure the GC is aware of this to optimise memory access patterns. The `numactl` command line tool can be used to check if your system is of non-uniform memory architecture. -You can install `numactl` with your distribution's package manager, For example on Ubuntu, you can run `sudo apt-get install numactl`. +You can install `numactl` with your distribution's package manager. For example on Ubuntu, you can run `sudo apt-get install numactl`. The command line option below can be used to enable NUMA-aware GC: @@ -41,7 +41,7 @@ If the size of the heap is too small, excessive time will be spent in GC compare It is recommended the max heap size is not greater that the physical memory on your system. If multiple JVMs are running the sum of their heaps must not exceed the total physical memory (the `free -h` command can be used to find the phyisical memory). This is to avoid the high latency accesses to access memory on disk from swapping during a full GC sweep. -Unfortunately there is no hard rule on which values to set. However a rule of thumb is to aim for 30% occupancy of the heap after a full GC. This requires running the application until a steady state has been reached. +Unfortunately, there is no hard rule on which values to set. However, a useful benchmark to apply is to aim for 30% occupancy of the heap after a full GC. This requires running the application until a steady state has been reached. ### Are the GC generation sizes appropriate? @@ -53,5 +53,5 @@ Use the following command-line flag adjust the ratio of young to old generations -XX:NewRatio= ``` -Additionally, the initial size and maximum size of the young generation can be modified with `-XX:NewSize` and `-XX:MaxNewSize` respectively. For more information, you can refer to the [factors affecting garbage collection performance](https://docs.oracle.com/en/java/javase/11/gctuning/factors-affecting-garbage-collection-performance.html#GUID-4ADBEDE9-5D52-4FBF-ADB2-431C3EB089C5) +Additionally, the initial size and maximum size of the young generation can be modified with `-XX:NewSize` and `-XX:MaxNewSize` respectively. For more information, see [Factors affecting Garbage Collection Performance](https://docs.oracle.com/en/java/javase/11/gctuning/factors-affecting-garbage-collection-performance.html#GUID-4ADBEDE9-5D52-4FBF-ADB2-431C3EB089C5). From 3e5bad43e33cc17199286bb05caefe15a02ea9a8 Mon Sep 17 00:00:00 2001 From: Maddy Underwood <167196745+madeline-underwood@users.noreply.github.com> Date: Wed, 11 Dec 2024 13:57:11 +0000 Subject: [PATCH 07/11] Tidied up review questions. --- .../java-gc-tuning/_review.md | 20 +++++++++---------- .../java-gc-tuning/optional_tuning.md | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/_review.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/_review.md index 2a8fd709a..c6293b7e5 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/_review.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/_review.md @@ -2,30 +2,30 @@ review: - questions: question: > - What is the purpose of garbage collection? + What is the purpose of Garbage Collection? answers: - - To manage memory by automatically reclaiming unused objects - - To manually manage memory allocation + - To manage memory by automatically reclaiming unused objects. + - To manually manage memory allocation. correct_answer: 1 explanation: > - Garbage collection is used to manage memory by automatically reclaiming memory occupied by objects that are no longer in use, thus preventing memory leaks and optimizing memory usage. + Garbage Collection is used to manage memory by automatically reclaiming memory occupied by objects that are no longer in use, to prevent memory leaks and optimize memory usage. - questions: question: > - Which JVM flag can be used to enable detailed garbage collection logging? + Which JVM flag can you use to enable detailed garbage collection logging? answers: - - -XX:+UseG1GC - - -XX:+PrintGCDetails + - -XX:+UseG1GC. + - -XX:+PrintGCDetails. correct_answer: 2 explanation: > The flag -XX:+PrintGCDetails enables detailed logging of garbage collection events, which helps in monitoring and tuning the GC performance. - questions: question: > - Which garbage collector is best suited for applications requiring very low latency in a heavily multi-threaded application? + Which Garbage Collector is best suited for applications requiring very low latency in a heavily multi-threaded application? answers: - - Serial GC - - ZGC + - Serial GC. + - ZGC. correct_answer: 2 explanation: > ZGC (Z Garbage Collector) is designed for applications requiring very low latency, as it aims to keep pause times below 10 milliseconds even for large heaps. diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md index b2974ab05..c0be0f4d3 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md @@ -26,7 +26,7 @@ In JDK8, to observe how the JVM is resizing an application, set the `-XX:+PrintA Non-uniform memory architecture(NUMA) occurs when the memory performance varies depending on which core the application is running on and where the data is in memory. This is a common occurrence if you are using a system with multiple sockets. If your system has multiple sockets you need to ensure the GC is aware of this to optimise memory access patterns. The `numactl` command line tool can be used to check if your system is of non-uniform memory architecture. -You can install `numactl` with your distribution's package manager. For example on Ubuntu, you can run `sudo apt-get install numactl`. +You can install `numactl` with your distribution's package manager. For example, on Ubuntu, you can run `sudo apt-get install numactl`. The command line option below can be used to enable NUMA-aware GC: @@ -39,7 +39,7 @@ The command line option below can be used to enable NUMA-aware GC: If the size of the heap is too small, excessive time will be spent in GC compared to the application logic. However disproportionately large heaps will result in longer GC pauses as there is more memory to parse. The `-Xmx ` and `-Xms ` options can be used to specify the maximum and minimum memory sizes respectively. If you know the heap size required based on data, setting the minimum and maximum values will slightly improve the performance since resizing will never take place. -It is recommended the max heap size is not greater that the physical memory on your system. If multiple JVMs are running the sum of their heaps must not exceed the total physical memory (the `free -h` command can be used to find the phyisical memory). This is to avoid the high latency accesses to access memory on disk from swapping during a full GC sweep. +It is recommended the max heap size is not greater that the physical memory on your system. If multiple JVMs are running the sum of their heaps must not exceed the total physical memory (the `free -h` command can be used to find the physical memory). This is to avoid the high latency accesses to access memory on disk from swapping during a full GC sweep. Unfortunately, there is no hard rule on which values to set. However, a useful benchmark to apply is to aim for 30% occupancy of the heap after a full GC. This requires running the application until a steady state has been reached. From d09439a3e4f08aee8cf140978b79cd7992d88307 Mon Sep 17 00:00:00 2001 From: Maddy Underwood <167196745+madeline-underwood@users.noreply.github.com> Date: Wed, 11 Dec 2024 14:12:54 +0000 Subject: [PATCH 08/11] Clarified title of external reference, spelling and grammar check. --- .../java-gc-tuning/Tuning Parameters.md | 2 +- .../servers-and-cloud-computing/java-gc-tuning/different_gcs.md | 2 +- .../java-gc-tuning/optional_tuning.md | 2 +- .../servers-and-cloud-computing/java-gc-tuning/purpose_of_gc.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Tuning Parameters.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Tuning Parameters.md index 5ce22b4e9..9d5c8ad2e 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Tuning Parameters.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Tuning Parameters.md @@ -73,5 +73,5 @@ This specifies the number of threads for parallel GC operations. Increasing this This 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. -See [this technical article](https://www.oracle.com/technical-resources/articles/java/g1gc.html) for more information of G1GC tuning. +See [Garbage First Garbage Collector Tuning](https://www.oracle.com/technical-resources/articles/java/g1gc.html) for more information of G1GC tuning. diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md index 1d4a29813..35e9d7b67 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/different_gcs.md @@ -34,7 +34,7 @@ Although collecting a region still necessitates pausing application threads, G1G ### ZGC and Shenandoah Garbage Collectors -Heap compaction time in Java Garbage Collection refers to the process of reorganizing live objects in memory to eliminate fragmentation. In the G1GC, heap compaction time is largely determined by the time spent relocating objects within memory, which requires pausing all application threads during the process. In contrast, the ZGC and Shenandoah Garbage Collectors can perform heap compaction concurrently while the application continues running, reducing pause times. ZGC and Shenandoah GCs use a form of locking to implement concurrent heap compaction in a lightweight manner. Starting from JDK version 15, ZGC became production-ready. +Heap compaction time in Java Garbage Collection refers to the process of reorganizing live objects in memory to eliminate fragmentation. In the G1GC, heap compaction time is determined by the time spent relocating objects within memory, which requires pausing all application threads during the process. In contrast, the ZGC and Shenandoah Garbage Collectors can perform heap compaction concurrently while the application continues running, reducing pause times. ZGC and Shenandoah GCs use a form of locking to implement concurrent heap compaction in a lightweight manner. Starting from JDK version 15, ZGC became production-ready. The ZGC and Shenandoah Garbage Collectors are particularly suited for applications that require ultra-low pause times and can benefit from concurrent garbage collection, making them ideal for large-scale, latency-sensitive applications such as real-time analytics, trading systems, and other interactive services. By allowing heap compaction to occur concurrently, these collectors significantly reduce application pauses compared to G1GC, which pauses all threads during compaction. diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md index c0be0f4d3..2e72d7efe 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md @@ -1,6 +1,6 @@ --- title: Intermediate GC Tuning Options -weight: 6 +weight: 7 ### FIXED, DO NOT MODIFY layout: learningpathall diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/purpose_of_gc.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/purpose_of_gc.md index 3ee92f9c1..0da03bd03 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/purpose_of_gc.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/purpose_of_gc.md @@ -12,7 +12,7 @@ Garbage Collection (GC) is the term used in programming to describe the concept In a programming language such as C, developers need to explicitly free variables once they are no longer required. Automatic memory management removes the requirement for this procedure, meaning that there is less potential for human error. -Generally, the Garbage Collector must perform three main tasks: +The Garbage Collector must perform three main tasks: * Find the objects to free. * Free the memory. From ea5ae0abbe5d83e3cd7481ad779217d2c133dfa2 Mon Sep 17 00:00:00 2001 From: Maddy Underwood <167196745+madeline-underwood@users.noreply.github.com> Date: Wed, 11 Dec 2024 14:25:10 +0000 Subject: [PATCH 09/11] Adjusting agency and tense. --- .../java-gc-tuning/optional_tuning.md | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md index 2e72d7efe..603b1507e 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md @@ -8,23 +8,27 @@ layout: learningpathall ## Optional Tuning Parameters -If you have an intermediate understanding of Java performance, you can experiment with the additional tuning options in this section to see how it impacts the performance of your application. This is a non-exhaustive list. Please see the 'Next Steps' tab for further reading. +If you have an intermediate understanding of Java performance, you can experiment with the additional tuning options in this section to see how it impacts the performance of your application. This is a non-exhaustive list. See *Next Steps* section for further reading. ### Which adaptive heap sizing strategy is being used? -The JVM attempts to find an optimal sizing solution within the bounds of the policies and parameters through adaptive sizing, varying the generation and heap sizes dynamically during execution. This is on the assumption that historic GC cycles will be similar to future GC cycles. This is generally true. +The JVM attempts to find an optimal sizing solution within the bounds of the policies and parameters through adaptive sizing, varying the generation and heap sizes dynamically during execution. This assumes that historic GC cycles are similar to future GC cycles. This is generally true. -However, in specific cases where you have existing knowledge of the heap requirements, for example a small, short-lived java utility, disabling adaptive sizing using the flag shown below can avoid the small overhead and time taken to resize. Note the `-` before the `UseAdaptiveSizePolicy` disables this feature. +However, in specific cases where you have existing knowledge of the heap requirements, for example with a small, short-lived java utility, disabling adaptive sizing using the flag shown below can avoid the small overhead and time taken to resize. + +{{% notice Note%}} +The`-` before the `UseAdaptiveSizePolicy` disables this feature. +{{% /notice %}} ```bash -XX:-UseAdaptiveSizePolicy ``` -In JDK8, to observe how the JVM is resizing an application, set the `-XX:+PrintAdaptiveSizePolicy` to print the information on generation resizing in the GC log. +In JDK8, to observe how the JVM resizes an application, set the `-XX:+PrintAdaptiveSizePolicy` to print the information on generation resizing in the GC log. ### Is your GC NUMA aware? -Non-uniform memory architecture(NUMA) occurs when the memory performance varies depending on which core the application is running on and where the data is in memory. This is a common occurrence if you are using a system with multiple sockets. If your system has multiple sockets you need to ensure the GC is aware of this to optimise memory access patterns. The `numactl` command line tool can be used to check if your system is of non-uniform memory architecture. +Non-Uniform Memory Architecture(NUMA) occurs when the memory performance varies depending on which core the application is running on and where the data is located in memory. This is a common occurrence if you are using a system with multiple sockets, where you need to ensure that the GC is aware of this to optimise memory access patterns. You can use the `numactl` command line tool to check if your system is of Non-Uniform Memory Architecture. You can install `numactl` with your distribution's package manager. For example, on Ubuntu, you can run `sudo apt-get install numactl`. @@ -35,17 +39,19 @@ The command line option below can be used to enable NUMA-aware GC: ``` -### Is the GC Heap Size Appropriate? +### Is the Garbage Collection Heap Size Appropriate? -If the size of the heap is too small, excessive time will be spent in GC compared to the application logic. However disproportionately large heaps will result in longer GC pauses as there is more memory to parse. The `-Xmx ` and `-Xms ` options can be used to specify the maximum and minimum memory sizes respectively. If you know the heap size required based on data, setting the minimum and maximum values will slightly improve the performance since resizing will never take place. +If the size of the heap is too small, excessive time is spent in GC compared to the application logic. However, disproportionately large heaps result in longer GC pauses as there is more memory to parse. You can use the `-Xmx ` and `-Xms ` options to specify the maximum and minimum memory sizes respectively. If you know the heap size required based on data, setting the minimum and maximum values slightly improves the performance since resizing never takes place. -It is recommended the max heap size is not greater that the physical memory on your system. If multiple JVMs are running the sum of their heaps must not exceed the total physical memory (the `free -h` command can be used to find the physical memory). This is to avoid the high latency accesses to access memory on disk from swapping during a full GC sweep. +It is recommended that the max heap size is not greater that the physical memory on your system. If multiple JVMs are running, the sum of their heaps must not exceed the total physical memory (the `free -h` command can be used to find the physical memory). This is to avoid the high latency accesses to access memory on disk from swapping during a full GC sweep. Unfortunately, there is no hard rule on which values to set. However, a useful benchmark to apply is to aim for 30% occupancy of the heap after a full GC. This requires running the application until a steady state has been reached. -### Are the GC generation sizes appropriate? +### Are the Garbage Collection generation sizes appropriate? + +Going a step further, garbage collectors (GCs) divide the heap into generations: young, survivor, and old. The young generation holds short-lived data, while the old generation holds long-lived data. This separation allows GCs to process the young generation more quickly, reducing pause times. It is recommended to hand-tune the generation sizes if you are an advanced java user. -Going a step further, garbage collectors (GCs) divide the heap into generations: young, survivor, and old. The young generation holds short-lived data, while the old generation holds long-lived data. This separation allows GCs to process the young generation more quickly, reducing pause times. It is recommended to hand tune the generation sizes if you are an advanced java user. As an example use case, in a Java application where startup performance is critical, tuning the young generation size can help. By increasing the young generation size, you can reduce the frequency of minor GCs during startup, leading to faster application initialization. +As an example use case, in a Java application where startup performance is critical, tuning the young generation size can help. By increasing the young generation size, you can reduce the frequency of minor GCs during startup, leading to faster application initialization. Use the following command-line flag adjust the ratio of young to old generations from the default value of 2 for all GC algorithms: From e137f7fe5791243900180d9a6526e39048fc443f Mon Sep 17 00:00:00 2001 From: Maddy Underwood <167196745+madeline-underwood@users.noreply.github.com> Date: Fri, 13 Dec 2024 10:27:27 +0000 Subject: [PATCH 10/11] Update Example_application.md Updated comment in code snippet in Example_application.md to address review comment: In a code snippet in Example_application.md a comment reads "Sleep for 1 second (1000 milliseconds)" whereas the program code two lines below reads "Thread.sleep(250);". The correction would be to change the comment to read "Sleep for 1/4 second (250 milliseconds)". This would then be consistent with the description above, which states that the example prints out four times a second. --- .../java-gc-tuning/Example_application.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Example_application.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Example_application.md index fd57cce6c..abb01708e 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Example_application.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/Example_application.md @@ -99,7 +99,7 @@ public class GenerateRandom { // Print random double System.out.println("Random Doubles: " + rand_dub1); - // Sleep for 1 second (1000 milliseconds) + // Sleep for 1/4 second (250 milliseconds) try { Thread.sleep(250); } catch (InterruptedException e) { From 872cb4c5a98477ec925e5eb7a87e45127c75e0ba Mon Sep 17 00:00:00 2001 From: Maddy Underwood <167196745+madeline-underwood@users.noreply.github.com> Date: Fri, 13 Dec 2024 10:38:52 +0000 Subject: [PATCH 11/11] Final fixes after AP review Comments addressed were: In optional_tuning.md there is a missing space between "Architecture(NUMA)". Again in optional_tuning.md: "This is to avoid the high latency accesses to access memory on disk from swapping during a full GC sweep.". Change "high latency accesses to access memory" -> "high latency cost to access memory". Again in optional_tuning.md "Use the following command-line flag adjust the ratio": "flag adjust" -> "flag to adjust". --- .../java-gc-tuning/optional_tuning.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md index 603b1507e..4673068a2 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md +++ b/content/learning-paths/servers-and-cloud-computing/java-gc-tuning/optional_tuning.md @@ -28,7 +28,7 @@ In JDK8, to observe how the JVM resizes an application, set the `-XX:+PrintAdapt ### Is your GC NUMA aware? -Non-Uniform Memory Architecture(NUMA) occurs when the memory performance varies depending on which core the application is running on and where the data is located in memory. This is a common occurrence if you are using a system with multiple sockets, where you need to ensure that the GC is aware of this to optimise memory access patterns. You can use the `numactl` command line tool to check if your system is of Non-Uniform Memory Architecture. +Non-Uniform Memory Architecture (NUMA) occurs when the memory performance varies depending on which core the application is running on and where the data is located in memory. This is a common occurrence if you are using a system with multiple sockets, where you need to ensure that the GC is aware of this to optimise memory access patterns. You can use the `numactl` command line tool to check if your system is of Non-Uniform Memory Architecture. You can install `numactl` with your distribution's package manager. For example, on Ubuntu, you can run `sudo apt-get install numactl`. @@ -43,7 +43,7 @@ The command line option below can be used to enable NUMA-aware GC: If the size of the heap is too small, excessive time is spent in GC compared to the application logic. However, disproportionately large heaps result in longer GC pauses as there is more memory to parse. You can use the `-Xmx ` and `-Xms ` options to specify the maximum and minimum memory sizes respectively. If you know the heap size required based on data, setting the minimum and maximum values slightly improves the performance since resizing never takes place. -It is recommended that the max heap size is not greater that the physical memory on your system. If multiple JVMs are running, the sum of their heaps must not exceed the total physical memory (the `free -h` command can be used to find the physical memory). This is to avoid the high latency accesses to access memory on disk from swapping during a full GC sweep. +It is recommended that the max heap size is not greater that the physical memory on your system. If multiple JVMs are running, the sum of their heaps must not exceed the total physical memory (the `free -h` command can be used to find the physical memory). This is to avoid the high latency cost to access memory on disk from swapping during a full GC sweep. Unfortunately, there is no hard rule on which values to set. However, a useful benchmark to apply is to aim for 30% occupancy of the heap after a full GC. This requires running the application until a steady state has been reached. @@ -53,7 +53,7 @@ Going a step further, garbage collectors (GCs) divide the heap into generations: As an example use case, in a Java application where startup performance is critical, tuning the young generation size can help. By increasing the young generation size, you can reduce the frequency of minor GCs during startup, leading to faster application initialization. -Use the following command-line flag adjust the ratio of young to old generations from the default value of 2 for all GC algorithms: +Use the following command-line flag to adjust the ratio of young to old generations from the default value of 2 for all GC algorithms: ```bash -XX:NewRatio=