Docker 镜像 JVM 调优
当我们使用Java环境基础镜像的时候,期望在启动 Docker 镜像的时候对JVM参数进行一定的调优,通常要么是启动的时候写死优化变量,但是这种方式不方便,还有就通过自定义环境变量JAVA_OPTS或者使用JAVA_TOOL_OPTIONS方式。
基于 JAVA_OPTS 环境变量(不推荐)
此方式需要 在 Dockerfile 中定义变量 JAVA_OPTS,并在启动命令中使用 JAVA_OPTS
Dockerfile 示例:
#FROM openjdk:11-jre-alpine
#FROM openjdk:11-jre-slim
#FROM openjdk:11-jdk-alpine
#FROM openjdk:11-jdk-slim
#FROM openjdk:11-jdk-oracle
#FROM openjdk:8-jre-alpine
#FROM openjdk:8-jre-slim
#FROM openjdk:8-jdk-alpine
#FROM openjdk:8-jdk-slim
#FROM openjdk:8-jdk-oracle
FROM openjdk:8-jdk-alpine
# 申明临时卷
VOLUME /logs
VOLUME /tmp
# 拷贝本地Jar包到根目录
ADD ./target/app.jar /
# 暴露端口
# EXPOSE 8100
#设置变量 JAVA_OPTS
ENV JAVA_OPTS="" #这样写会以shell方式执行,会替换变量
# 挂着启动脚本
ENTRYPOINT java ${JAVA_OPTS} -jar app.jar
#下面这样写法不行,他只是拼接不会识别变量
#ENTRYPOINT ["java", "${JAVA_OPTS}", "-jar","app.jar"]
然后;运行 docker run 命令;运行时通过-e重置覆盖环境变量中JAVA_OPTS参数信息。
docker run -e JAVA_OPTS='-Xmx1344M -Xms1344M -Xmn448M -XX:MaxMetaspaceSize=192M -XX:MetaspaceSize=192M'
进入容器
docker exec -it 容器ID/名称 /bin/bash
查看java应用,就可以看到
ps -ef | grep java
结果如下:
/myapp # ps -ef|grep java1 root 2:49 java -Xmx1344M -Xms1344M -Xmn448M -XX:MaxMetaspaceSize=192M -XX:MetaspaceSize=192M -Djava.security.egd=file:/dev/./urandom -jar /app.jar466 root 0:00 grep java
基于 JAVA_TOOL_OPTIONS 环境变量(推荐)
JAVA_TOOL_OPTIONS 就是个环境变量,它会被JNI API的JNI_CreateJavaVM函数使用。因为JAVA_TOOL_OPTIONS是被被JNI_CreateJavaVM调用的,顾名思义是创建VM
各种OPTIONS的区别:
也许你经常遇到JAVA_OPTS、JAVAOPTIONS和JAVA_TOOL_OPTIONS,那么他们有什么不同呢?
JAVA_OPTS:常用于一些应用的配置,如Tomcat,但它一般不作为环境变量,也不能被JVM识别的,是那些应用的自定义配置;
JAVAOPTIONS:也是作为环境变量来替代命令行参数的,但它是JVM厂家自定义的,可以覆盖JAVA_TOOL_OPTIONS,但各厂家的不同,JAVAOPTIONS是Oracle的JVM,而IBM的则是用IBM_JAVA_OPTIONS。
JAVA_TOOL_OPTIONS:是标准的,所有虚拟机都能识别和应用的。
https://www.jb51.net/article/207937.htm
- name: JAVA_TOOL_OPTIONS
value: '-Xms256M -Xmx512M -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:GCLogFileSize=20m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/logs/heaperror.log -Xloggc:/logs/gcerror.log'
分配内存 堆配置推荐
1G -Xmx512M -Xms512M -Xmn256M -XX:MaxMetaspaceSize=128M -XX:MetaspaceSize=64M
2G -Xmx1344M -Xms1344M -Xmn448M -XX:MaxMetaspaceSize=192M -XX:MetaspaceSize=192M
3G-Xmx2048M -Xms2048M -Xmn768M -XX:MaxMetaspaceSize=256M -XX:MetaspaceSize=256M
4G-Xmx2688M -Xms2688M -Xmn960M -XX:MaxMetaspaceSize=256M -XX:MetaspaceSize=256M
5G-Xmx3392M -Xms3392M -Xmn1216M -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M
6G-Xmx4096M -Xms4096M -Xmn1536M -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M
7G-Xmx4736M -Xms4736M -Xmn1728M -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M
8G-Xmx5440M -Xms5440M -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:GCLogFileSize=20m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/logs/heaperror.log -Xloggc:/logs/gcerror.log
“-XX:InitiatingHeapOccupancyPercent=60”, “-XX:MinHeapDeltaBytes=262144”, “-XX:MetaspaceSize=128m”, “-XX:MaxMetaspaceSize=256m”, “-XX:InitialHeapSize=256M”, “-XX:MaxHeapSize=256M”, “-XX:+PrintGCDetails”, “-XX:+PrintGCTimeStamps”, “-XX:+UseG1GC”, “-XX:GCLogFileSize=20m”, “-XX:+HeapDumpOnOutOfMemoryError”, “-XX:HeapDumpPath=/logs/heaperror.log”, “-Xloggc:/logs/gcerror.log”,
- 2核4G
-Xms2048m -Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseGCLogFileRotation -XX:HeapDumpPath=/home/admin/edas-container/logs/oom.log -XX:ParallelGCThreads=4 -XX:MaxMetaspaceSize=512m -Xloggc:/home/admin/edas-container/logs/ -XX:NumberOfGCLogFiles=30 -XX:+PrintGCDateStamps -XX:GCLogFileSize=100m -XX:MetaspaceSize=512m -XX:+UseConcMarkSweepGC -XX:+PrintGC
- 4核8G
-Xms5120m -Xmx5120m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseGCLogFileRotation -XX:HeapDumpPath=/home/admin/edas-container/logs/oom.log -XX:ParallelGCThreads=4 -XX:MaxMetaspaceSize=512m -XX:NewSize=512m -Xloggc:/home/admin/edas-container/logs/ -XX:NumberOfGCLogFiles=30 -XX:+PrintGCDateStamps -XX:GCLogFileSize=1024m -XX:MetaspaceSize=512m -XX:+UseConcMarkSweepGC -XX:+PrintGC
- name: JAVA_TOOL_OPTIONS
value: >-
-Xmx4096M -Xms4096M -Xmn1536M -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M -XX:MetaspaceSize=256M
-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap
-XX:+UseG1GC -XX:MaxGCPauseMillis=200m -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps
-XX:GCLogFileSize=20m -XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/logs/heaperror.log
-Xloggc:/logs/gcerror.log
常用的JVM配置参数有哪些?
-Xms:初始大小内存,默认为物理内存的1/64等价于-XX:InitialHeapSize
-Xmx:最大分配内存,默认为物理内存的1/4等价于-XX:MaxHeapSize
-Xss:设置单个线程栈的大小,一般默认为512k~1024k等价于-XX:ThreadStackSize
当值等于0的时候,代表使用得是默认大小
-Xmn:设置年轻代大小
-XX:MetaspaceSize:设置元空间大小(元空间与永久代最大的区别为:元空间并不在虚拟机中,而使用的是本地内存,因此,元空间只收本地内存的限制)
手动设置:-XX:MetaspaceSize=1024m
典型设置案例
-XX:+PrintGCDetails:输出详细GC收集日志信息
当堆内存不够的话,会爆出OOM错误
-XX:SurvivorRatio:设置新生代中 eden 和 S0/S1 空间比例,默认 -XX:SurvivorRatio=8,Eden : S0 : S1 = 8 : 1 : 1
-XX:SurvivorRatio=4==》Eden : S0 : S1 = 4 : 1 : 1
-XX:NewRatio:配置年轻代和老年代在堆结构的占比,默认 -XX:NewRatio=2 新生代占1,老年代占2,年轻代占整个堆的 1/3
-XX:NewRatio=4 新生代占1,老年代占4,年轻代占整个堆的 1/5
-XX:MaxTenuringThreshold:设置垃圾最大年龄。默认是15。
-XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入老年代。对于老年代比较多的应用,可以提高效率。如果此值设置为一个较大的值,则年前对象会在Survivor区进行多次复制,这样可以增加对象在年轻代的存活时间,增加在年轻代被回收的概率!
在这里插入图片描述
因为是由四位二进制数组成,所以垃圾最大年龄为15.因为0-15是16个数字
最后编辑:Jeebiz 更新时间:2024-11-27 12:52