如何在容器中設置Java應用程序以避免內存問題和OOM?

根本原因

如何在容器中設置Java應用程序以避免內存問題和OOM?

OOM

默認情況下,java應用程序將使用主機內存的1/4,而不是容器。這是Java運行的默認定義,容器外部沒有選項。其餘的內存用於交換,緩存等。

<code>$ docker run -m 400MB openjdk:8 java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XshowSettings:vm -version
VM settings:
    Max. Heap Size (Estimated): 112.00M
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM
 
openjdk version "1.8.0_171"
OpenJDK Runtime Environment (build 1.8.0_171-8u171-b11-1~deb9u1-b11)
OpenJDK 64-Bit Server VM (build 25.171-b11, mixed mode)/<code>

解決

最佳配置取決於應用程序內存要求。

Java版本 < 10

從Java 8u131到Java 9,您可以使用試驗性的“ UseCGroupMemoryLimitForHeap”。這樣就可以使用容器的1/4來針對容器的內存限制來自我管理內存值。

<code>$ docker run -m 400MB openjdk:8 java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XshowSettings:vm -version
VM settings:
    Max. Heap Size (Estimated): 112.00M
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM
 
openjdk version "1.8.0_171"
OpenJDK Runtime Environment (build 1.8.0_171-8u171-b11-1~deb9u1-b11)
OpenJDK 64-Bit Server VM (build 25.171-b11, mixed mode)/<code>

您可以通過結合使用Java中的“ -Xmx”和docker上的內存限制來避免使用實驗性設置。您可以使用另一個選項,“-XX:MaxRAM =”,這可以使您完全修復java使用的ram的最大數量。可以將其設置為與docker內存限制相同的數量,並且將像選項“ UseCGroupMemoryLimitForHeap”一樣工作。不同之處在於它不是自動的。

<code>$ docker run -m 400MB openjdk:8 java -XX:MaxRAM=400m -Xmx300m -XX:MaxRAMFraction=1 -XshowSettings:vm -version
VM settings:
    Max. Heap Size: 300.00M
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM
 
openjdk version "1.8.0_171"
OpenJDK Runtime Environment (build 1.8.0_171-8u171-b11-1~deb9u1-b11)
OpenJDK 64-Bit Server VM (build 25.171-b11, mixed mode)/<code>

您可以使用-XX:MaxRAMFraction = 1優化堆內存的使用,該內存將幾乎所有可用內存用作最大堆:

<code>$ docker run -m 400MB openjdk:8 java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1 -XshowSettings:vm -version
VM settings:
    Max. Heap Size (Estimated): 356.00M
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM
 
openjdk version "1.8.0_171"
OpenJDK Runtime Environment (build 1.8.0_171-8u171-b11-1~deb9u1-b11)
OpenJDK 64-Bit Server VM (build 25.171-b11, mixed mode)/<code>

Java版本10

現在,它已完全集成到Java 10中:

<code>$ docker run -m 400MB openjdk:10 java -XshowSettings:vm -version
VM settings:
    Max. Heap Size (Estimated): 121.81M
    Using VM: OpenJDK 64-Bit Server VM
 
openjdk version "10.0.2" 2018-07-17
OpenJDK Runtime Environment (build 10.0.2+13-Debian-1)
OpenJDK 64-Bit Server VM (build 10.0.2+13-Debian-1, mixed mode)/<code>

像10之前的版本一樣,您可以使用-XX:MaxRAMFraction = 1優化堆內存的使用,它將幾乎所有可用的內存用作最大堆。但是此選項已被棄用,並將在未來的新版本中刪除:

<code>docker run -m 400MB openjdk:10 java -XshowSettings:vm -XX:MaxRAMFraction=1 -version
OpenJDK 64-Bit Server VM warning: Option MaxRAMFraction was deprecated in version 10.0 and will likely be removed in a future release.                                                                            
VM settings:
    Max. Heap Size (Estimated): 386.69M
    Using VM: OpenJDK 64-Bit Server VM
 
openjdk version "10.0.2" 2018-07-17
OpenJDK Runtime Environment (build 10.0.2+13-Debian-2)
OpenJDK 64-Bit Server VM (build 10.0.2+13-Debian-2, mixed mode)/<code>


譯文鏈接:https://success.docker.com/article/java-app-is-killed-by-docker


分享到:


相關文章: