2021-09-28 docker 配置JVM参数及常用命令使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021-09-28 docker 配置JVM参数及常用命令使用相关的知识,希望对你有一定的参考价值。

参考技术A 为什么设置了 -Xmx 还是被 kill

宿主机内存如下,

默认情况下,JVM的Max Heap Size是系统内存的1/4,那么JVM将的默认Heap≈4G。

参考这篇文章 被kill问题之2:Docker环境下Java应用的JVM设置(容器中的JVM资源该如何被安全的限制)

前文提到还有另外一种方法解决 JVM 内存超限的问题,这种方法可以让 JVM 自动感知 docker 容器的 cgroup 限制,从而动态的调整堆内存大小,感觉挺不错的。我们也来试一下这种方法,看看效果如何 ; )
查看下当前tomcat是否支持该参数
-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap

往下翻,找到了要配置的参数,表示当前jvm支持该参数,最终参数如下,/var/jvm/log目录记得创建

加到Catalina.sh中

[root@localhost webapps]# docker commit -a "fengjian" -m "tomcat8+jdk8+jvm参数优化" cd50041ea188 tomcat:8.5.70-jdk8-jvmG1

进入到容器之后,想查看容器使用的内存情况,报错如下

参考 Docker 中无法使用 JDK jmap之 Can't attach to the process: ptrace(PTRACE_ATTACH问题
在启动容器时增加参数
docker run --cap-add=SYS_PTRACE
完整启动如下
docker run --name central-kitchen-kxg -d -p 9093:8080 -v /home/dockerms/data/central-kitchen-kxg/webapps:/usr/local/tomcat/webapps -e TZ=Asia/Shanghai --cap-add=SYS_PTRACE tomcat:8.5.70-jdk8-jvmG1

关于docker运行Java程序JVM配置参数使用jconsole的简单量化过程

1.如果服务可以本地启动那么尽量在本地进行参数预估

2.如果服务不能本地启动,可以使用远程连接方式进行预估

 

3.衡量要点:

Java程序运行大致分为三块:堆内存,非堆内存(虚拟机栈,方法区,本地方法栈,程序计数器),堆外内存.

docker容器中运行除了Java程序还需要为其余程序余力内存空间.这里假设统一预留50M空间.

3.1 堆内存的量化

堆内存主要分为几个区域,新生代,复制区,老年代.考虑GC会大量回收堆内存空间,只要不发生内存逸出和内存

泄露情况,堆内存能支持一定的并发即可.无线上数据参考情况可以,简单预估QPS为3进行测试堆内存可能大小.

这里以POIService为例子,启动项目后连接后观察情况如下.

访问接口调用时,其各项数据.

图中可以看出 堆内存最小可以到50M最大可大300M左右,堆内存主要用于实例化对象.我们这里预估下 150M就够用了.

为了线上稳定再次基础上提升10%, 可配置固定内存大小为165M即参数 -Xmx165M -Xms165M

线程没有及时进行回收,导致线程量一直在增加.需要优化相关代码.不然会导致线程占用内存持续增加,JVM会为每个线程单独

分配空间.

3.2 非堆内存量化

图中可以看出,非堆内存使用量不是很大大概65M左右.

设置参数:-XX:PermSize=65M -XX:MaxPermSize=130M (1.8以前)

-XX:MetaspaceSize = 100M (1.8以后)

这里预估为 165 + 100 + 20(对外内存) + 50 = 335M 这里直接给400M

这里要说下.因为资源有限才这么设置,如果资源足够可以进行GC时间的衡量来设置相关参数.

-Xmx180M -Xms180M -XX:MaxDirectMemorySize=20M -XX:MetaspaceSize=100M

调整后效果还可以,这里主意,GC会导致STW可能影响响应时间,要去衡量那个是当前需要的.

 

远程调试尝试

远程连接配置如下:

[program:configservice]

command=java -Xmx180M -Xms180M -XX:MaxDirectMemorySize=20M -XX:MetaspaceSize=100M -Djava.rmi.server.hostname=106.75.105.45 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=19999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -jar -Dfile.encoding=UTF-8 configservice.jar

没有限制前top观察到内存使用快到1G了,限制后如下:

一天后再次观察数据如下:

还是比较稳定的,目前使用内存 350M左右.线上给400M.

 

以上是关于2021-09-28 docker 配置JVM参数及常用命令使用的主要内容,如果未能解决你的问题,请参考以下文章

关于docker运行Java程序JVM配置参数使用jconsole的简单量化过程

Docker环境下Spring Boot应用内存飙升分析与解决

springboot之docker启动参数传递

Docker——Tomcat JVM 内存配置

Docker——Tomcat JVM 内存配置

JDK 8中的针对DOCKER的JVM参数