加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

如何防止Java超出容器内存限制?

发布时间:2020-12-15 08:27:15 所属栏目:Java 来源:网络整理
导读:我正在Docker容器中运行一个 Java程序,其内存限制为4GB.我已将最大堆设置为3GB,但Java程序仍然超出限制并被杀死(OOMKilled). 我的问题是:我如何配置Java以尊重设置的容器限制并抛出OutOfMemoryException而不是尝试分配超出限制并让主机内核踢它的屁股? 更
我正在Docker容器中运行一个 Java程序,其内存限制为4GB.我已将最大堆设置为3GB,但Java程序仍然超出限制并被杀死(OOMKilled).

我的问题是:我如何配置Java以尊重设置的容器限制并抛出OutOfMemoryException而不是尝试分配超出限制并让主机内核踢它的屁股?

更新:我是一位经验丰富的Java开发人员,对JVM有一个公平的理解.我知道如何设置最大堆,但我想知道是否有人知道如何设置JVM进程从操作系统声明的总内存限制.

解决方法

当Java应用程序在容器内执行时,JVM人体工程学(负责根据主机的功能动态分配资源)不知道它是在容器内运行,它计算Java应用程序要使用的资源数量基于正在执行容器的主机.鉴于此,如果为容器设置限制并不重要,JVM将把主机的资源作为进行计算的基础.

从JDK 8u131和JDK 9开始,有一个实验性VM选项,允许JVM人体工程学从CGgroups读取内存值.要启用它,您必须将以下标志传递给JVM:

-XX:+UnlockExperimentalVMOptions and -XX:+UseCGroupMemoryLimitForHeap

如果启用这些标志,JVM将知道正在容器内运行并且将使JVM符合人体工程学,以根据容器限制而不是主机的功能来计算应用程序的资源.

启用标志:

$java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -jar app.jar

您可以使用ENV变量将JVM选项动态传递到容器.

例:

运行您的应用程序的命令类似于:

$java ${JAVA_OPTIONS} -jar app.jar

docker run命令需要传递ENV变量,如下所示:

$docker run -e JAVA_OPTIONS="-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap" myJavaImage

希望这可以帮助!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读