|
6 | 6 | [id="nodes-cluster-resource-configure-jdk_{context}"]
|
7 | 7 | = Understanding OpenJDK settings for {product-title}
|
8 | 8 |
|
9 |
| -The default OpenJDK settings do not work well with containerized |
10 |
| -environments. As a result, some additional Java memory |
11 |
| -settings must always be provided whenever running the OpenJDK in a container. |
| 9 | +The default OpenJDK settings do not work well with containerized environments. As a result, some additional Java memory settings must always be provided whenever running the OpenJDK in a container. |
12 | 10 |
|
13 |
| -The JVM memory layout is complex, version dependent, and describing it in detail |
14 |
| -is beyond the scope of this documentation. However, as a starting point for |
15 |
| -running OpenJDK in a container, at least the following three memory-related |
16 |
| -tasks are key: |
| 11 | +The JVM memory layout is complex, version dependent, and describing it in detail is beyond the scope of this documentation. However, as a starting point for running OpenJDK in a container, at least the following three memory-related tasks are key: |
17 | 12 |
|
18 | 13 | . Overriding the JVM maximum heap size.
|
19 | 14 |
|
20 |
| -. Encouraging the JVM to release unused memory to the operating system, if |
21 |
| - appropriate. |
| 15 | +. Encouraging the JVM to release unused memory to the operating system, if appropriate. |
22 | 16 |
|
23 | 17 | . Ensuring all JVM processes within a container are appropriately configured.
|
24 | 18 |
|
25 |
| -Optimally tuning JVM workloads for running in a container is beyond the scope of |
26 |
| -this documentation, and may involve setting multiple additional JVM options. |
| 19 | +Optimally tuning JVM workloads for running in a container is beyond the scope of this documentation, and may involve setting multiple additional JVM options. |
27 | 20 |
|
28 | 21 | [id="nodes-cluster-resource-configure-jdk-heap_{context}"]
|
29 | 22 | == Understanding how to override the JVM maximum heap size
|
30 | 23 |
|
31 |
| -For many Java workloads, the JVM heap is the largest single consumer of memory. |
32 |
| -Currently, the OpenJDK defaults to allowing up to 1/4 (1/`-XX:MaxRAMFraction`) |
33 |
| -of the compute node's memory to be used for the heap, regardless of whether the |
34 |
| -OpenJDK is running in a container or not. It is therefore *essential* to |
35 |
| -override this behavior, especially if a container memory limit is also set. |
36 |
| - |
37 |
| -There are at least two ways the above can be achieved: |
38 |
| - |
39 |
| -* If the container memory limit is set and the experimental options are |
40 |
| - supported by the JVM, set `-XX:+UnlockExperimentalVMOptions |
41 |
| - -XX:+UseCGroupMemoryLimitForHeap`. |
42 |
| -+ |
43 |
| -[NOTE] |
44 |
| -==== |
45 |
| -The `UseCGroupMemoryLimitForHeap` option has been removed in JDK 11. Use `-XX:+UseContainerSupport` instead. |
46 |
| -==== |
47 |
| -+ |
48 |
| -This sets `-XX:MaxRAM` to the container memory limit, and the maximum heap size |
49 |
| -(`-XX:MaxHeapSize` / `-Xmx`) to 1/`-XX:MaxRAMFraction` (1/4 by default). |
50 |
| - |
51 |
| -* Directly override one of `-XX:MaxRAM`, `-XX:MaxHeapSize` or `-Xmx`. |
52 |
| -+ |
53 |
| -This option involves hard-coding a value, but has the advantage of allowing a |
54 |
| -safety margin to be calculated. |
| 24 | +OpenJDK defaults to using a maximum of 25% of available memory (recognizing any container memory limits in place) for "heap" memory. This default value is conservative, and, in a properly-configured container environment, this value would result in 75% of the memory assigned to a container being mostly unused. A much higher percentage for the JVM to use for heap memory, such as 80%, is more suitable in a container context where memory limits are imposed on the container level. |
| 25 | + |
| 26 | +Most of the Red{nbsp}Hat containers include a startup script that replaces the OpenJDK default by setting updated values when the JVM launches. |
| 27 | + |
| 28 | +For example, the Red{nbsp}Hat build of OpenJDK containers have a default value of 80%. This value can be set to a different percentage by defining the `JAVA_MAX_RAM_RATIO` environment variable. |
| 29 | + |
| 30 | +For other OpenJDK deployements, the default value of 25% can be changed using the following command: |
| 31 | + |
| 32 | +.Example |
| 33 | +[source,terminal] |
| 34 | +---- |
| 35 | +$ java -XX:MaxRAMPercentage=80.0 |
| 36 | +---- |
55 | 37 |
|
56 | 38 | [id="nodes-cluster-resource-configure-jdk-unused_{context}"]
|
57 | 39 | == Understanding how to encourage the JVM to release unused memory to the operating system
|
58 | 40 |
|
59 |
| -By default, the OpenJDK does not aggressively return unused memory to the |
60 |
| -operating system. This may be appropriate for many containerized Java |
61 |
| -workloads, but notable exceptions include workloads where additional active |
62 |
| -processes co-exist with a JVM within a container, whether those additional |
63 |
| -processes are native, additional JVMs, or a combination of the two. |
| 41 | +By default, the OpenJDK does not aggressively return unused memory to the operating system. This may be appropriate for many containerized Java workloads, but notable exceptions include workloads where additional active processes co-exist with a JVM within a container, whether those additional processes are native, additional JVMs, or a combination of the two. |
64 | 42 |
|
65 |
| -Java-based agents can use the following JVM arguments to encourage the JVM |
66 |
| -to release unused memory to the operating system: |
| 43 | +Java-based agents can use the following JVM arguments to encourage the JVM to release unused memory to the operating system: |
67 | 44 |
|
68 | 45 | [source,terminal]
|
69 | 46 | ----
|
70 | 47 | -XX:+UseParallelGC
|
71 | 48 | -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10 -XX:GCTimeRatio=4
|
72 |
| --XX:AdaptiveSizePolicyWeight=90. |
| 49 | +-XX:AdaptiveSizePolicyWeight=90 |
73 | 50 | ----
|
74 | 51 |
|
75 |
| -These arguments are intended to return heap |
76 |
| -memory to the operating system whenever allocated memory exceeds 110% of in-use |
77 |
| -memory (`-XX:MaxHeapFreeRatio`), spending up to 20% of CPU time in the garbage |
78 |
| -collector (`-XX:GCTimeRatio`). At no time will the application heap allocation |
79 |
| -be less than the initial heap allocation (overridden by `-XX:InitialHeapSize` / |
80 |
| -`-Xms`). Detailed additional information is available |
81 |
| -link:https://developers.redhat.com/blog/2014/07/15/dude-wheres-my-paas-memory-tuning-javas-footprint-in-openshift-part-1/[Tuning Java's footprint in OpenShift (Part 1)], |
82 |
| -link:https://developers.redhat.com/blog/2014/07/22/dude-wheres-my-paas-memory-tuning-javas-footprint-in-openshift-part-2/[Tuning Java's footprint in OpenShift (Part 2)], |
83 |
| -and at |
84 |
| -link:https://developers.redhat.com/blog/2017/04/04/openjdk-and-containers/[OpenJDK |
85 |
| -and Containers]. |
| 52 | +These arguments are intended to return heap memory to the operating system whenever allocated memory exceeds 110% of in-use memory (`-XX:MaxHeapFreeRatio`), spending up to 20% of CPU time in the garbage collector (`-XX:GCTimeRatio`). At no time will the application heap allocation be less than the initial heap allocation (overridden by `-XX:InitialHeapSize` / `-Xms`). Detailed additional information is available link:https://developers.redhat.com/blog/2014/07/15/dude-wheres-my-paas-memory-tuning-javas-footprint-in-openshift-part-1/[Tuning Java's footprint in OpenShift (Part 1)], link:https://developers.redhat.com/blog/2014/07/22/dude-wheres-my-paas-memory-tuning-javas-footprint-in-openshift-part-2/[Tuning Java's footprint in OpenShift (Part 2)], and at link:https://developers.redhat.com/blog/2017/04/04/openjdk-and-containers/[OpenJDK and Containers]. |
86 | 53 |
|
87 | 54 | [id="nodes-cluster-resource-configure-jdk-proc_{context}"]
|
88 | 55 | == Understanding how to ensure all JVM processes within a container are appropriately configured
|
89 | 56 |
|
90 |
| -In the case that multiple JVMs run in the same container, it is essential to |
91 |
| -ensure that they are all configured appropriately. For many workloads it will |
92 |
| -be necessary to grant each JVM a percentage memory budget, leaving a perhaps |
93 |
| -substantial additional safety margin. |
| 57 | +In the case that multiple JVMs run in the same container, it is essential to ensure that they are all configured appropriately. For many workloads it will be necessary to grant each JVM a percentage memory budget, leaving a perhaps substantial additional safety margin. |
94 | 58 |
|
95 | 59 | Many Java tools use different environment variables (`JAVA_OPTS`, `GRADLE_OPTS`, and so on) to configure their JVMs and it can be challenging to ensure that the right settings are being passed to the right JVM.
|
96 | 60 |
|
97 |
| -The `JAVA_TOOL_OPTIONS` environment variable is always respected by the OpenJDK, |
98 |
| -and values specified in `JAVA_TOOL_OPTIONS` will be overridden by other options |
99 |
| -specified on the JVM command line. By default, to ensure that these options are |
100 |
| -used by default for all JVM workloads run in the Java-based agent image, the {product-title} Jenkins Maven agent image sets: |
| 61 | +The `JAVA_TOOL_OPTIONS` environment variable is always respected by the OpenJDK, and values specified in `JAVA_TOOL_OPTIONS` will be overridden by other options specified on the JVM command line. By default, to ensure that these options are used by default for all JVM workloads run in the Java-based agent image, the {product-title} Jenkins Maven agent image sets the following variable: |
101 | 62 |
|
102 | 63 | [source,terminal]
|
103 | 64 | ----
|
104 |
| -JAVA_TOOL_OPTIONS="-XX:+UnlockExperimentalVMOptions |
105 |
| --XX:+UseCGroupMemoryLimitForHeap -Dsun.zip.disableMemoryMapping=true" |
| 65 | +JAVA_TOOL_OPTIONS="-Dsun.zip.disableMemoryMapping=true" |
106 | 66 | ----
|
107 | 67 |
|
108 |
| -[NOTE] |
109 |
| -==== |
110 |
| -The `UseCGroupMemoryLimitForHeap` option has been removed in JDK 11. Use `-XX:+UseContainerSupport` instead. |
111 |
| -==== |
112 |
| - |
113 |
| -This does not guarantee that additional options are not required, but is |
114 |
| -intended to be a helpful starting point. |
| 68 | +This does not guarantee that additional options are not required, but is intended to be a helpful starting point. |
0 commit comments