Skip to content

Commit f339366

Browse files
authored
Merge pull request #210446 from SteveSaunders1952/v-ssaunders-KaiqianYang
App restart issues caused by out-of-memory issues editorial pass
2 parents f9a853d + ca0ed36 commit f339366

14 files changed

+360
-0
lines changed

articles/spring-apps/breadcrumb/toc.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
- name: Azure Spring Apps
99
tocHref: /azure/developer/java/migration/
1010
topicHref: /azure/spring-apps/index
11+
- name: Azure Spring Apps
12+
tocHref: /azure/developer/java/containers/
13+
topicHref: /azure/spring-cloud/index
1114
- name: Azure Spring Apps
1215
tocHref: /cli/azure/
1316
topicHref: /azure/spring-apps/index
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
---
2+
title: Java memory management
3+
titleSuffix: Azure Spring Apps
4+
description: Introduces concepts for Java memory management to help you understand Java applications in Azure Spring Apps.
5+
author: karlerickson
6+
ms.author: kaiqianyang
7+
ms.service: spring-cloud
8+
ms.topic: conceptual
9+
ms.date: 07/15/2022
10+
ms.custom: devx-track-java
11+
---
12+
13+
# Java memory management
14+
15+
> [!NOTE]
16+
> Azure Spring Apps is the new name for the Azure Spring Cloud service. Although the service has a new name, you'll see the old name in some places for a while as we work to update assets such as screenshots, videos, and diagrams.
17+
18+
**This article applies to:** ✔️ Basic/Standard tier ✔️ Enterprise tier
19+
20+
This article describes various concepts related to Java memory management to help you understand the behavior of Java applications hosted in Azure Spring Apps.
21+
22+
## Java memory model
23+
24+
A Java application's memory has several parts, and there are different ways to divide the parts. This article discusses Java memory as divided into heap memory, non-heap memory, and direct memory.
25+
26+
### Heap memory
27+
28+
Heap memory stores all class instances and arrays. Each Java virtual machine (JVM) has only one heap area, which is shared among threads.
29+
30+
Spring Boot Actuator can observe the value of heap memory. Spring Boot Actuator takes the heap value as part of `jvm.memory.used/committed/max`. For more information, see the [jvm.memory.used/committed/max](tools-to-troubleshoot-memory-issues.md#jvmmemoryusedcommittedmax) section in [Tools to troubleshoot memory issues](tools-to-troubleshoot-memory-issues.md).
31+
32+
Heap memory is divided into *young generation* and *old generation*. These terms are described in the following list, along with related terms.
33+
34+
- *Young generation*: all new objects are allocated and aged in young generation.
35+
36+
- *Eden space*: new objects are allocated in Eden space.
37+
- *Survivor space*: objects will be moved from Eden to survivor space after surviving one garbage collection cycle. Survivor space can be divided to two parts: s1 and s2.
38+
39+
- *Old generation*: also called *tenured space*. Objects that have remained in the survivor spaces for a long time will be moved to old generation.
40+
41+
Before Java 8, another section called *permanent generation* was also part of the heap. Starting with Java 8, permanent generation was replaced by metaspace in non-heap memory.
42+
43+
### Non-heap memory
44+
45+
Non-heap memory is divided into the following parts:
46+
47+
- The part of non-heap memory that replaced the permanent generation (or *permGen*) starting with Java 8. Spring Boot Actuator observes this section and takes it as part of `jvm.memory.used/committed/max`. In other words, `jvm.memory.used/committed/max` is the sum of heap memory and the former permGen part of non-heap memory. The former permanent generation is composed of the following parts:
48+
49+
- *Metaspace*, which stores the class definitions loaded by class loaders.
50+
- *Compressed class space*, which is for compressed class pointers.
51+
- *Code cache*, which stores native code compiled by JIT.
52+
53+
- Other memory such as the thread stack, which isn't observed by Spring Boot Actuator.
54+
55+
### Direct memory
56+
57+
Direct memory is native memory allocated by `java.nio.DirectByteBuffer`, which is used in third party libraries like nio and gzip.
58+
59+
Spring Boot Actuator doesn't observe the value of direct memory.
60+
61+
The following diagram summarizes the Java memory model described in the previous section.
62+
63+
:::image type="content" source="media/concepts-for-java-memory-management/java-memory-model.png" alt-text="Diagram of the Java memory model." border="false":::
64+
65+
## Java garbage collection
66+
67+
There are three terms regarding of Java Garbage Collection (GC): "Minor GC", "Major GC", and "Full GC". These terms aren't clearly defined in the JVM specification. Here, we consider "Major GC" and "Full GC" to be equivalent.
68+
69+
Minor GC performs when Eden space is full. It removes all dead objects in young generation and moves live objects to from Eden space to s1 of survivor space, or from s1 to s2.
70+
71+
Full GC or major GC does garbage collection in the entire heap. Full GC can also collect parts like metaspace and direct memory, which can be cleaned only by full GC.
72+
73+
The maximum heap size influences the frequency of minor GC and full GC. The maximum metaspace and maximum direct memory size influence full GC.
74+
75+
When you set the maximum heap size to a lower value, garbage collections occur more frequently, which slow the app a little, but better limits the memory usage. When you set the maximum heap size to a higher value, garbage collections occur less frequently, which may create more out-of-memory (OOM) risk. For more information, see the [Types of out-of-memory issues](how-to-fix-app-restart-issues-caused-by-out-of-memory.md#types-of-out-of-memory-issues) section of [App restart issues caused by out-of-memory issues](how-to-fix-app-restart-issues-caused-by-out-of-memory.md).
76+
77+
Metaspace and direct memory can be collected only by full GC. When metaspace or direct memory is full, full GC will occur.
78+
79+
## Java memory configurations
80+
81+
The following sections describe important aspects of Java memory configuration.
82+
83+
### Java containerization
84+
85+
Applications in Azure Spring Apps run in container environments. For more information, see [Containerize your Java applications](/azure/developer/java/containers/overview?toc=/azure/spring-cloud/toc.json&bc=/azure/spring-cloud/breadcrumb/toc.json).
86+
87+
### Important JVM options
88+
89+
You can configure the maximum size of each part of memory by using JVM options. You can set JVM options by using Azure CLI commands or through the Azure portal. For more information, see the [Modify configurations to fix problems](tools-to-troubleshoot-memory-issues.md#modify-configurations-to-fix-problems) section of [Tools to troubleshoot memory issues](tools-to-troubleshoot-memory-issues.md).
90+
91+
The following list describes the JVM options:
92+
93+
- Heap size configuration
94+
95+
- `-Xms` sets the initial heap size by absolute value.
96+
- `-Xmx` sets the maximum heap size by absolute value.
97+
- `-XX:InitialRAMPercentage` sets the initial heap size by the percentage of heap size / app memory size.
98+
- `-XX:MaxRAMPercentage` sets the maximum heap size by the percentage of heap size / app memory size.
99+
100+
- Direct memory size configuration
101+
102+
- `-XX:MaxDirectMemorySize` sets the maximum direct memory size by absolute value. For more information, see [MaxDirectMemorySize](https://docs.oracle.com/en/java/javase/11/tools/java.html#GUID-3B1CE181-CD30-4178-9602-230B800D4FAE__GUID-2E02B495-5C36-4C93-8597-0020EFDC9A9C) in the Oracle documentation.
103+
104+
- Metaspace size configuration
105+
106+
- `-XX:MaxMetaspaceSize` sets the maximum metaspace size by absolute value.
107+
108+
### Default maximum memory size
109+
110+
The following sections describe how default maximum memory sizes are set.
111+
112+
#### Default maximum heap size
113+
114+
Azure Spring Apps sets the default maximum heap memory size to about 50%-80% of app memory for Java apps. Specifically, Azure Spring Apps uses the following settings:
115+
116+
- If the app memory < 1 GB, the default maximum heap size will be 50% of app memory.
117+
- If 1 GB <= the app memory < 2 GB, the default maximum heap size will be 60% of app memory.
118+
- If 2 GB <= the app memory < 3 GB, the default maximum heap size will be 70% of app memory.
119+
- If 3 GB <= the app memory, the default maximum heap size will be 80% of app memory.
120+
121+
#### Default maximum direct memory size
122+
123+
When the maximum direct memory size isn't set using JVM options, the JVM automatically sets the maximum direct memory size to the value returned by [Runtime.getRuntime.maxMemory()](https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#maxMemory--). This value is approximately equal to the maximum heap memory size. For more information, see the [JDK 8 VM.java file](http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/a71d26266469/src/share/classes/sun/misc/VM.java#l282&gt;%20jdk8).
124+
125+
### Memory usage layout
126+
127+
Heap size is influenced by your throughput. Basically, when configuring, you can keep the default maximum heap size, which leaves reasonable memory for other parts.
128+
129+
The metaspace size depends on the complexity of your code, such as the number of classes.
130+
131+
The direct memory size depends on your throughput and your use of third party libraries like nio and gzip.
132+
133+
The following list describes a typical memory layout sample for 2-GB apps. You can refer to this list to configure your memory size settings.
134+
135+
- Total Memory (2048M)
136+
- Heap memory: Xmx is 1433.6M (70% of total memory). The reference value of daily memory usage is 1200M.
137+
- Young generation
138+
- Survivor space (S0, S1)
139+
- Eden space
140+
- Old generation
141+
- Non-heap memory
142+
- Observed part (observed by Spring Boot Actuator)
143+
- Metaspace: the daily usage reference value is 50M-256M
144+
- Code cache
145+
- Compressed class space
146+
- Not observed part (not observed by Spring Boot Actuator): the daily usage reference value is 150M-250M.
147+
- Thread stack
148+
- GC, internal symbol and other
149+
- Direct memory: the daily usage reference value is 10M-200M.
150+
151+
The following diagram shows the same information. Numbers in grey are the reference values of daily memory usage.
152+
153+
:::image type="content" source="media/concepts-for-java-memory-management/2-gb-sample.png" alt-text="Diagram of typical memory layout for 2-GB apps." border="false":::
154+
155+
Overall, when configuring maximum memory sizes, you should consider the usage of each part in memory, and the sum of all maximum sizes shouldn't exceed total available memory.
156+
157+
## Java OOM
158+
159+
OOM means the application is out of memory. There are two different concepts: container OOM and JVM OOM. For more information, see [App restart issues caused by out-of-memory issues](how-to-fix-app-restart-issues-caused-by-out-of-memory.md).
160+
161+
## See also
162+
163+
- [App restart issues caused by out-of-memory issues](how-to-fix-app-restart-issues-caused-by-out-of-memory.md)
164+
- [Tools to troubleshoot memory issues](tools-to-troubleshoot-memory-issues.md)
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
---
2+
title: App restart issues caused by out-of-memory issues
3+
titleSuffix: Azure Spring Apps
4+
description: Explains how to understand out-of-memory (OOM) issues for Java applications in Azure Spring Apps.
5+
author: karlerickson
6+
ms.author: kaiqianyang
7+
ms.service: spring-cloud
8+
ms.topic: conceptual
9+
ms.date: 07/15/2022
10+
ms.custom: devx-track-java
11+
---
12+
13+
# App restart issues caused by out-of-memory issues
14+
15+
> [!NOTE]
16+
> Azure Spring Apps is the new name for the Azure Spring Cloud service. Although the service has a new name, you'll see the old name in some places for a while as we work to update assets such as screenshots, videos, and diagrams.
17+
18+
**This article applies to:** ✔️ Basic/Standard tier ✔️ Enterprise tier
19+
20+
This article describes out-of-memory (OOM) issues for Java applications in Azure Spring Apps.
21+
22+
## Types of out-of-memory issues
23+
24+
There are two types of out-of-memory issues: container OOM and JVM OOM.
25+
26+
- Container OOM, also called *system OOM*, occurs when the available app memory has run out. Container OOM issue causes app restart events, which are reported in the **Resource Health** section of the Azure portal. Normally, container OOM is caused by incorrect memory size configurations.
27+
28+
- JVM OOM occurs when the amount of used memory has reached the maximum size set in JVM options. JVM OOM won't cause an app to restart. Normally, JVM OOM is a result of bad code, which you can find by looking for `java.lang.OutOfMemoryError` exceptions in the application log. JVM OOM has a negative effect on application and Java Profiling tools, such as Java Flight Recorder.
29+
30+
This article focuses on how to fix container OOM issues. To fix JVM OOM issues, check tools such as heap dump, thread dump, and Java Flight Recorder. For more information, see [Capture heap dump and thread dump manually and use Java Flight Recorder in Azure Spring Apps](how-to-capture-dumps.md).
31+
32+
## Fix app restart issues due to OOM
33+
34+
The following sections describe the tools, metrics, and JVM options that you can use to diagnose and fix container OOM issues.
35+
36+
### View alerts on the Resource health page
37+
38+
The **Resource health** page on the Azure portal shows app restart events due to container OOM, as shown in the following screenshot:
39+
40+
:::image type="content" source="media/how-to-fix-app-restart-issues-caused-by-out-of-memory/out-of-memory-alert-resource-health.png" alt-text="Screenshot of Azure portal showing Azure Spring Apps Resource Health page with OOM message highlighted." lightbox="media/how-to-fix-app-restart-issues-caused-by-out-of-memory/out-of-memory-alert-resource-health.png":::
41+
42+
### Configure memory size
43+
44+
The metrics *App memory Usage*, `jvm.memory.used`, and `jvm.memory.committed` provide a view of memory usage. For more information, see the [Metrics](tools-to-troubleshoot-memory-issues.md#metrics) section of [Tools to troubleshoot memory issues](tools-to-troubleshoot-memory-issues.md). Configure the maximum memory sizes in JVM options to ensure that memory is under the limit.
45+
46+
The sum of the maximum memory sizes of all the parts in the [Java memory model](concepts-for-java-memory-management.md#java-memory-model) should be less than the real available app memory. To set your maximum memory sizes, see the typical memory layout described in the [Memory usage layout](concepts-for-java-memory-management.md#memory-usage-layout) section of [Java memory management](concepts-for-java-memory-management.md).
47+
48+
Find a balance when you set the maximum memory size. When you set the maximum memory size too high, there's a risk of container OOM. When you set the maximum memory size too low, there's a risk of JVM OOM, and garbage collection will be of and will slow down the app.
49+
50+
#### Control heap memory
51+
52+
You can set the maximum heap size by using the `-Xms`, `-Xmx`, `-XX:InitialRAMPercentage`, and `-XX:MaxRAMPercentage` JVM options.
53+
54+
You may need to adjust the maximum heap size settings when the value of `jvm.memory.used` is too high in the metrics. For more information, see the [jvm.memory.used/committed/max](tools-to-troubleshoot-memory-issues.md#jvmmemoryusedcommittedmax) section of [Tools to troubleshoot memory issues](tools-to-troubleshoot-memory-issues.md).
55+
56+
#### Control direct memory
57+
58+
It's important to set the `-XX:MaxDirectMemorySize` JVM option for the following reasons:
59+
60+
- You may not notice when frameworks such as nio and gzip use direct memory.
61+
- Garbage collection of direct memory is only handled during full garbage collection, and full garbage collection occurs only when the heap is near full.
62+
63+
Normally, you can set `MaxDirectMemorySize` to a value less than the app memory size minus the heap memory minus the non-heap memory.
64+
65+
#### Control metaspace
66+
67+
You can set the maximum metaspace size by setting the `-XX:MaxMetaspaceSize` JVM option. The `-XX:MetaspaceSize` option sets the threshold value to trigger full garbage collection.
68+
69+
Metaspace memory is usually stable.
70+
71+
## See also
72+
73+
- [Java memory management](concepts-for-java-memory-management.md)
74+
- [Tools to troubleshoot memory issues](tools-to-troubleshoot-memory-issues.md)
21 KB
Loading
22.8 KB
Loading
Loading
33.9 KB
Loading
185 KB
Loading
108 KB
Loading
47.3 KB
Loading

0 commit comments

Comments
 (0)