Skip to content

Commit 6e11c19

Browse files
Update jvm-memory-tuning.md
1 parent 9475f03 commit 6e11c19

1 file changed

Lines changed: 39 additions & 61 deletions

File tree

content/en/docs/deployment/private-cloud/private-cloud-deploy/jvm-memory-tuning.md

Lines changed: 39 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -7,75 +7,61 @@ weight: 10
77
---
88
## Introduction
99

10-
Mendix Runtime and any Mendix apps run in a Java Virtual Machine.
11-
12-
Most Java Virtual Machines (including the one used in Mendix on Kubernetes) are based on the HotSpot Java VM.
13-
The HotSpot VM uses a garbage collector to free up unused memory.o
14-
15-
Running the garbage collector causes a negative performance impact; the Hotspot VM tries to only run garbage collection when absolutely necessary (for example, when memory usage reaches a certain threshold).
10+
Mendix Runtime and any Mendix apps run in a Java Virtual Machine. Most Java Virtual Machines (including the one used in Mendix on Kubernetes) are based on the HotSpot Java VM. The HotSpot VM uses a garbage collector to free up unused memory. However, running the garbage collector causes a negative performance impact. The Hotspot VM tries to only run garbage collection when absolutely necessary (for example, when memory usage reaches a certain threshold).
1611

1712
{{% alert color="info" %}}
1813
For a comprehensive guide explaining how the HotSpot VM performs garbage collection, see the [official Java documentation](https://docs.oracle.com/en/java/javase/21/gctuning/index.html).
1914
{{% /alert %}}
2015

21-
## Memory tuning
16+
## Memory Tuning
2217

23-
In most cases, Mendix on Kubernetes doesn't need advanced memory tuning.
24-
Starting with Operator version 2.26, the default memory settings have been aligned with Mendix Cloud and are based on typical Mendix app usage patterns.
18+
In most cases, Mendix on Kubernetes does not need advanced memory tuning. Starting with Operator version 2.26, the default memory settings have been aligned with Mendix Cloud and are based on typical Mendix app usage patterns.
2519

2620
{{% alert color="warning" %}}
27-
Manual adjusting JVM memory usage is only needed in some cases - when the default memory settings leave unused memory.
21+
Manual adjusting JVM memory usage is only needed in some cases, when the default memory settings leave unused memory.
2822
{{% /alert %}}
2923

30-
### Types of memory
24+
### Types of Memory
3125

3226
In the HotSpot VM, memory is split into two regions, **Heap** and **Non-Heap**.
3327

34-
* **Heap** memory is used to store temporary _data_, including microflow variables, entities and internal state of the Mendix Runtime and third-party libraries.
35-
* **Non-Heap** memory stores _code_, internal Java VM data and data from non-Java components, such as the [BAPI Connector](/appstore/modules/sap/sap-bapi-connector/#setup-environment) or machine learning modules from [ML Kit](/refguide/machine-learning-kit/).
28+
* **Heap** memory is used to store temporary data, including microflow variables, entities, and internal states of the Mendix Runtime and third-party libraries.
29+
* **Non-Heap** memory stores code, internal Java VM data and data from non-Java components, such as the [BAPI Connector](/appstore/modules/sap/sap-bapi-connector/#setup-environment) or machine learning modules from [ML Kit](/refguide/machine-learning-kit/).
3630

37-
There's a fixed boundary between **Heap** and **Non-Heap** memory: any memory reserved for the **Heap** cannot be used for any other purpose; all remaining memory will be assigned to the **Non-Heap** region.
31+
There is a fixed boundary between **Heap** and **Non-Heap** memory. Any memory reserved for the heap cannot be used for any other purpose. All remaining memory is assigned to the **Non-Heap** region.
3832

3933
{{< figure src="/attachments/deployment/private-cloud/private-cloud-deploy/jvm-memory-overview.png" class="no-border" >}}
4034

41-
It's not possible to dynamically adjust the amount of **Heap** and **Non-Heap** regions of a running app, this needs to be specified before starting an app.
35+
It is not possible to dynamically adjust the amount of **Heap** and **Non-Heap** regions of a running app. This needs to be specified before starting an app.
4236

43-
### Default memory allocation{#default-memory-allocation}
37+
### Default Memory Allocation {#default-memory-allocation}
4438

4539
Starting with Operator version 2.26, the default memory settings use the following rules:
4640

4741
| Container memory limit | JVM non-heap size |
48-
|------------------------|-------------------|
49-
| Less than 2 GB | Half of the limit (but at least 300 MB) |
50-
| Between 2 and 4 GB | 1 GB |
51-
| Between 4 and 8 GB | 1.5 GB |
52-
| Between 8 and 16 GB | 2 GB |
53-
| Between 16 and 32 GB | 3 GB |
54-
| 32 GB or more | 4 GB |
42+
| --- | --- |
43+
| Less than 2 GB | Half of the limit (but at least 300 MB) |
44+
| Between 2 and 4 GB | 1 GB |
45+
| Between 4 and 8 GB | 1.5 GB |
46+
| Between 8 and 16 GB | 2 GB |
47+
| Between 16 and 32 GB | 3 GB |
48+
| 32 GB or more | 4 GB |
5549

5650
All other memory is allocated to the heap.
5751

5852
{{% alert color="info" %}}
59-
Older Operator versions don't set any memory configuration.
60-
In this case, the HotSpot VM allocates 25% of the memory limit to heap memory, and the rest is assigned to non-heap memory.
61-
This assignment is not optimal, as typical Mendix apps primarily benefit from heap memory.
53+
Older Operator versions do not set any memory configuration. In this case, the HotSpot VM allocates 25% of the memory limit to heap memory, and the rest is assigned to non-heap memory. This assignment is not optimal, as typical Mendix apps primarily benefit from heap memory.
6254
{{% /alert %}}
6355

64-
### Metrics-based tuning
56+
### Metrics-Based Tuning
6557

6658
{{% alert color="info" %}}
67-
Instead of freeing memory, the HotSpot VM prefers to recycle/reuse it.
68-
When looking at total memory usage in a container (for example using `kubectl top pods` or data collected by `kube-state-metrics`),
69-
the total memory usage will not reflect internal details.
70-
71-
For example, the JVM **Heap** might be underutilized, but will show as "used memory" in the container memory usage.
72-
73-
To have a clear picture of how memory is allocated and used, use Prometheus metrics.
59+
Instead of freeing memory, the HotSpot VM prefers to recycle/reuse it. When looking at total memory usage in a container (for example using `kubectl top pods` or data collected by `kube-state-metrics`), the total memory usage will not reflect internal details. For example, the JVM **Heap** might be underutilized, but will show as *used memory* in the container memory usage. To have a clear picture of how memory is allocated and used, use Prometheus metrics.
7460
{{% /alert %}}
7561

76-
For examples how to read JVM memory usage graphs, see the [Java Memory Usage](/refguide/java-memory-usage/) document.
62+
For examples how to read JVM memory usage graphs, see [Java Memory Usage](/refguide/java-memory-usage/).
7763

78-
### Adjusting memory in Mendix on Kubernetes
64+
### Adjusting Memory in Mendix on Kubernetes
7965

8066
In a [Standalone environment](/developerportal/deploy/private-cloud-operator/#edit-cr), the JVM heap size can be adjusted in the `jvmMemorySettings` section of the `MendixApp` CR.
8167

@@ -99,56 +85,48 @@ spec:
9985
10086
Removing the `jvmMemorySettings` section will switch to the [default memory allocation](#default-memory-allocation) settings.
10187

102-
Starting with Operator version 2.26, the JVM heap size should be adjusted as documented in this section.
103-
If you have an environment using any of the following custom JVM options, they _will not be applied_ to the app configuration (will be removed):
88+
Starting with Operator version 2.26, the JVM heap size should be adjusted as documented in this section. If you have an environment using any of the following custom JVM options, they will not be applied to the app configuration and will instead be removed:
10489

10590
* `-Xms` - minimal heap size
10691
* `-Xmx` - heap size limit
10792
* `-XX:MinRAMPercentage` - heap size limit, in percentages for environments with less than 250MB of container memory
10893
* `-XX:MaxRAMPercentage` - heap size limit, in percentages for environments with more than 250MB of container memory
10994
* `-XX:InitialRAMPercentage` - minimal heap size, in percentages
11095

111-
## Addressing memory issues
96+
## Addressing Memory Issues
11297

113-
On a typical desktop system and many server environments, reaching or exceeding the memory limit is not a problem.
98+
On a typical desktop system and many server environments, reaching or exceeding the memory limit is not a problem. The operating system will move some of the memory contents to a storage device such as an SSD or hard drive. However, this will likely cause a major performance penalty, and in Kubernetes is [disabled by default](https://kubernetes.io/docs/concepts/cluster-administration/swap-memory-management/).
11499

115-
The operating system will move some of the memory contents to a storage device such as an SSD or hard drive.
116-
However, this will likely cause a major performance penalty, and in Kubernetes is [disabled by default](https://kubernetes.io/docs/concepts/cluster-administration/swap-memory-management/).
100+
When an app tries to use more memory than its container memory limit, it will be terminated by Kubernetes (OOMKilled) and will effectively crash. To prevent performance degradation and the app from crashing, it might need its memory to be adjusted.
117101

118-
When an app tries to use more memory than it's container memory limit, it will be terminated by Kubernetes (OOMKilled) and will effectively crash.
102+
### Addressing Out Of Memory Crashes
119103

120-
To prevent performance degradation and the app from crashing, it might need its memory to be adjusted.
121-
122-
### Addressing OOMKilled crashes
123-
124-
An OOMKilled (Out Of Memory-killed) event happens when an app attempts to use more memory than specified in its container limit:
104+
An *OOMKilled* (Out Of Memory-killed) event happens when an app attempts to use more memory than specified in its container limit:
125105

126106
{{< figure src="/attachments/deployment/private-cloud/private-cloud-deploy/jvm-nonheap-full.png" class="no-border" >}}
127107

128-
This will show as a container restarting with an `OOMKilled` exit code:
108+
This shows as a container restarting with an `OOMKilled` exit code:
129109

130110
{{< figure src="/attachments/deployment/private-cloud/private-cloud-deploy/jvm-memory-oomkilled.png" class="no-border" >}}
131111

132-
To address this issue:
112+
To address this issue, choose one of the following options:
133113

134-
* Recommended fix: increase the core resource memory (_requests_ and _limits_).
135-
* Alternatively, if the Prometheus metrics show that the heap memory usage is low: decrease the heap memory size.
114+
* Recommended fix: increase the core resource memory (**requests** and **limits**).
115+
* Alternatively, if the Prometheus metrics show that the heap memory usage is low, decrease the heap memory size.
136116

137117
{{% alert color="info" %}}
138-
This can also happen if a node is overcommitted (not enough available memory for app pods).
139-
140-
To prevent overcommitment, adjust the memory _requests_ to match the container _limits_.
118+
This can also happen if a node is overcommitted (not enough available memory for app pods). To prevent overcommitment, adjust the memory **requests** to match the container **limits**.
141119
{{% /alert %}}
142120

143-
### Addressing java.lang.OutOfMemoryError exceptions
121+
### Addressing Java.lang.OutOfMemoryError Exceptions
144122

145-
A `java.lang.OutOfMemoryError` exception happens when the JVM **Heap** is full and doesn't have enough available memory to perform an action (such as a Microflow or a Java Custom Action).
123+
A `java.lang.OutOfMemoryError` exception happens when the JVM heap is full and does not have enough available memory to perform an action (such as a Microflow or a Java Custom Action).
146124

147125
{{< figure src="/attachments/deployment/private-cloud/private-cloud-deploy/jvm-heap-full.png" class="no-border" >}}
148126

149-
This will show as a `java.lang.OutOfMemoryError: Java heap space` error message in the logs.
127+
This shows as a `java.lang.OutOfMemoryError: Java heap space` error message in the logs.
150128

151-
To address this issue:
129+
To address this issue, choose one of the following options:
152130

153-
* Recommended fix: increase the core resource memory (_requests_ and _limits_).
154-
* Alternatively, if the container has a lot of free, unused memory: increase the heap memory size.
131+
* Recommended fix: increase the core resource memory (**requests** and **limits**).
132+
* Alternatively, if the container has a lot of free, unused memory, increase the heap memory size.

0 commit comments

Comments
 (0)