参考:java
https://qingmu.io/2018/12/17/How-to-securely-limit-JVM-resources-in-a-container/#moredocker
默认状况下,JVM的Max Heap Size是系统内存的1/4,假如咱们系统是8G,那么JVM将的默认Heap≈2G。apache
# docker logs compose_cwtpro-back_1后端
Exception in thread "http-nio-8080-Acceptor-0" java.lang.OutOfMemoryError: GC overhead limit exceededtomcat
28-Feb-2019 08:59:19.035 SEVERE [http-nio-8080-ClientPoller-0] org.apache.tomcat.util.net.NioEndpoint$Poller.eventsbash
java.lang.OutOfMemoryError: GC overhead limit exceededapp
Exception in thread "http-nio-8080-exec-89" java.lang.OutOfMemoryError: GC overhead limit exceededless
Exception in thread "http-nio-8080-exec-58" java.lang.OutOfMemoryError: GC overhead limit exceededjvm
Exception in thread "http-nio-8080-exec-123" java.lang.OutOfMemoryError: GC overhead limit exceeded.net
# docker exec -it compose_cwtpro-back_1 bash
# java -XshowSettings:vm -version
从监控页面获取的信息是,在故障时间点,后端业务的内存使用量忽然飙升到接近4.3G,所以致使OOM
设置参数:
JAVA_OPTS="-server -Xms6g -Xmx6g -XX:PermSize=256m -XX:MaxPermSize=512m -XX:-OmitStackTraceInFastThrow" //因为compose文件里面没有声明相关jvm参数,所以采用默认。致使初始最大堆栈为系统内存的1/4(4G)。最终忽然的流量上升,致使OOM。
验证设置是否有效:
# docker exec -it 2f24707d7a97 bash
# ps -ef | grep java
# jinfo -flag MaxHeapSize 7 //打印对应pid的最大堆栈
对比主91.17,设置未重启及JAVA_OPTS未生效的:
3.87G 基本与截图一中经过java -XshowSettings:vm -version获取的最大堆栈符合(容器启动未限制容器可以使用内存,默认读取/proc/meminfo为最大能够内存,未设置docker启动限制cpu及内存状况下,默认MaxHeapSize为可用最大内存的1/4)
查看堆内存中的对象数目、大小统计直方图,若是带上live则只统计活对象,以下:
# jmap -histo:live 26590 | less
用jmap把进程内存使用状况dump到文件中,再用jhat分析查看。jmap进行dump命令格式以下:
# jmap -dump:format=b,file=/tmp/v2x_dump 7
//拷贝出来
kubectl cp deploy--user-6ff76fdbcf-cmdgh:/application/map_dump /root