dockerfile 配置 jdk1.8版本>=java 8u191 java 8u191+ UseContainerSupport默认开启
docker jvm配置
参考1:
docker run
--cap-add=SYS_PTRACE
--ulimit core=-1
-m 3060M
-e JAVA_OPTS="
-server
-XX:+UseG1GC
-Xmx2048m
-Xms2048m
-XX:+UnlockExperimentalVMOptions
-XX:+UseCGroupMemoryLimitForHeap
-XX:MaxRAMPercentage=70.0
-XX:NewRatio=2
-XX:+PrintGCDetails
-XX:+PrintHeapAtGC
-Xloggc:/data/logs/gc.log #打印gc信息
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/data/logs/heapdump.hprof
--spring.profiles.active=prod
"
参考2:
docker run
--cap-add=SYS_PTRACE // 激活jmap功能
--ulimit core=-1 // 激活heapdump
-m 2048M // 容器内存限制
-e JAVA_OPTS="
-server
-XX:+UseG1GC
-XX:+UnlockExperimentalVMOptions // 激活jvm尊重容器限制
-XX:+UseCGroupMemoryLimitForHeap // 激活jvm尊重容器限制
-XX:MaxRAMPercentage=70.0 // jvm Xmx 占容器内存百分比,示例即Xmx=1648*0.8。此处供参考,自行调试,取值必须为double
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/data/logs/heapdump.hprof
"
dockerfile jvm配置
ENV JAVA_OPTS="-server -Xmx1g -Xms1g -Xmn512m -XX:SurvivorRatio=8 -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -XX:+UseParallelGC -XX:ParallelGCThreads=4 -XX:+UseParallelOldGC -XX:+UseAdaptiveSizePolicy -XX:+PrintGCDetails -XX:+PrintTenuringDistribution -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/heapdump.hprof -Xloggc:/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10M"
ENTRYPOINT java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar /app.jar
或者
-e JAVA_OPTS='-server -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Xmx1024m -Xms1024m -Xmn512m -XX:SurvivorRatio=8 -XX:ParallelGCThreads=8 -XX:ConcGCThreads=8 -XX:G1ConcRefinementThreads=4 -XX:-CICompilerCountPerCPU -XX:CICompilerCount=3 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/logs/heapdump.hprof'
docker 内存限制:
-m 1024M
--memory-swap 1024M
注意:
docker镜像的内存上限,不能全部给“-Xmx”。因为JVM消耗的内存不仅仅是Heap JVM = Heap + Method Area + Constant Pool + Thread Stack * num of thread 所以Xmx的值要小于镜像上限内存
查看jvm 配置信息
docker exec -it xxx /bin/sh
java -XX:+PrintCommandLineFlags 打印jvm启动参数配置
java -XX:+PrintGCDetails 打印GC运行信息
java -XshowSettings:vm -version 打印jvm参数信息
jinfo -flags pid 查看jvm参数配置 容器内pid默认为1
jinfo -flag MaxHeapSize 1 打印对应pid的最大堆栈
jstat -gcutil 1 1000 100 一秒一次共100次统计
jmap -histo:live 26590 | less 查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象
jmap -heap 1 查看堆配置以及使用大小
gc信息统计,pid一般是1
jmap -histo 1 查看每个class的实例数目,内存占用,类全名信息
free -h 查看剩余内存
jmap -dump:live,format=b,file=m.hprof 1 容器内执行
docker cp 容器的name:m.hprof /data0
jmap -histo:live pid > pid.txt 查看当前java程序中内个对象的数量和占用空间
jmap -histo pid | head -n10 查看前10行的值
排查思路: 1、程序正常运行时,下载一次dump文件 2、间隔2到3个小时,再下载一次dump文件 3、使用MAT,(Eclipse Memory 分析工具) 对比2次jvm的内存dump文件,看增加了哪些对象,预计这些对象就是引起内存溢出的原因
内存<8G 基础配置 | 内存>8G 基础配置 | -server -XX:+DisableExplicitGC -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses -XX:+CMSClassUnloadingEnabled -XX:+ParallelRefProcEnabled -XX:+CMSScavengeBeforeRemark -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps -XX:ErrorFile=/var/app/gc/hs_err_pid%p.log -XX:HeapDumpPath=/var/app/gc -Xloggc:/var/app/gc/gc%t.log | -server -XX:+DisableExplicitGC -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:+ParallelRefProcEnabled -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps -XX:ErrorFile=/var/app/gc/hs_err_pid%p.log -XX:HeapDumpPath=/var/app/gc -Xloggc:/var/app/gc/gc%t.log |
参考文档: 容器内 JAVA 应用内存溢出问题分析
JVM 内存区域大小参数设置
Java内存区域与内存溢出异常
JVM各种内存溢出是否产生dump
JVM参数调优(内存溢出解决办法)
记一次JVM内存溢出排查过程
容器环境JVM内存配置最佳实践
看完这篇,再也不用焦虑如何写dockerfile了
dockerfile指定jvm参数
docker环境无法执行jmap命令解决办法
使用Dockerfile从0开始制作自己的docker镜像
|