zoukankan      html  css  js  c++  java
  • 容器中的Java堆大小调整:快速,轻松

    在上一篇博客中,我们已经看到Java进行了改进,可以根据正在运行的环境(即物理机或容器(码头工人))识别内存。java的最初问题是,它无法弄清楚它是否在容器中运行,并且它曾经为容器运行所在的整个硬件捕获内存。(请参阅  -ttps://blogs.oracle.com/java/java-on-container-like-a-pro

    现在,在容器中运行的Java程序能够识别cgroup限制并根据该限制分配内存(堆)(如果我们未指定以前定义的最小和最大堆大小)。因此,我们可以在容器中运行Java程序并适当地利用硬件内存,但是我们可以确定Java程序是否根据cgroup定义使用了堆大小?

    我们可以通过XshowSettings:category解决此问题  。 这是一个方便的HotSpot JVM标志(Java启动器java的选项)是-XshowSettings选项。Oracle Java启动器描述页面中对此选项进行了如下描述:

    -XshowSettings:category
    显示设置并继续。此选项的可能类别参数包括:

    all

    显示所有类别的设置。这是默认值。

    locale

    显示与语言环境相关的设置。

    properties

    显示与系统属性相关的设置。

    vm

    显示JVM的设置。

    [Java技术说明中描述的这些类型的标志-  如   https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html ]

    showSettings标志提供了有关该JVM中运行的程序的许多详细信息,但是,我们的兴趣是找出内存利用率,因此我们将坚持使用->  -XshowSettings:vm -version

    让我们通过运行一个简单的容器程序而不指定cgroup标志(这会通知Java该程序正在Java容器中运行)来验证这一点。

    (我将容器内存设置为100MB,而JVM将最大堆设置为3.24G)

    [root java-8]# docker run -m 100MB oracle-server-jre java -XshowSettings:vm -version

    VM settings:

        Max. Heap Size (Estimated): 3.24G

        Ergonomics Machine Class: server

        Using VM: Java HotSpot(TM) 64-Bit Server VM

    java version "1.8.0_181"

    Java(TM) SE Runtime Environment (build 1.8.0_181-b13)

    Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

    我们可以清楚地看到Java Heap正在捕获硬件可用的堆,但是docker大小仅指定为100 mb。现在,让我们告诉Java程序正在容器内运行并查看结果。

    仅使用jdk Docker的Java版本1.8.0_181(包括解锁实验版和具有内存1GB MB规范的Cgroup限制) 

    [root]# docker run -m 1GB oracle-server-jre java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XshowSettings:vm -version
    VM settings:
        Max. Heap Size (Estimated): 228.00M
        Ergonomics Machine Class: server
        Using VM: Java HotSpot(TM) 64-Bit Server VM

    java version "1.8.0_181"
    Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
    Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

    JVM能够检测到只有1GB的容器,并将最大堆设置为228M,这几乎是可用总大小的1/4。

    我们可以看到Java Heap设置为docker大小的1/4,而Docker则使用了3/4的其余内存,但是如果我们的容器不需要3/4内存,该怎么办,  

    如果容器或程序配置不需要那么多的内存,那么这不是对内存的正确利用。Java堆与容器大小之间的比率是在JVM代码中定义的,所以问题是-我们可以配置该比率吗? 

    是的,Java通过提供另一种选择来更改容器内存和Java堆大小的比率而做得很好。Java引入了另一个标志作为  MaxRAMFraction  (该标志的默认值为4,因此堆大小占容器大小的1/4,我们可以通过显式定义它来更改它)

    我们定义了RAM分数= 2,这使堆大小几乎占总数的50%。

    [root]# docker run -m 1GB oracle-server-jre java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=2 -XshowSettings:vm -version
    VM settings:    
        Max. Heap Size (Estimated): 455.50M
        Ergonomics Machine Class: server
        Using VM: Java HotSpot(TM) 64-Bit Server VM

    java version "1.8.0_181"
    Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
    Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

    堆大小大约达到容器总大小的50%。

    现在,我们也可以根据Java程序的舒适程度来更改该比率,但这又导致了另一种想法,即如果将该比率定义为1,则可以安全地运行容器?(但是JVM不会捕获全部容器内存,并且会留下一些内存来运行其他一些容器程序,例如容器调试外壳(docker exec)和诊断程序,OS进程等。如果程序或容器在负载下需要更多内存,则它将杀死容器,因此-XX:MaxRAMFraction=2 ,如果我们要自定义默认的JVM比率(这似乎是最安全的比率),我觉得定义最小比率似乎是安全的。

     

  • 相关阅读:
    vuex状态管理
    vue3.0创建一个项目
    Django + Vue
    Django部署
    django简单使用
    Django模型
    Centos7编译openjdk8源码
    深入了解final
    深入了解java值传递
    java自带的Logger日志系统
  • 原文地址:https://www.cnblogs.com/coder306/p/13087588.html
Copyright © 2011-2022 走看看