线上OutOfMemory问题,线上宕机问题处理
抛出问题?
有没有遇到过程序启动后就宕机的情况?
有没有遇到过程序被请求几次后CPU飙升,内存震荡严重的,接口数据响应超级慢然后紧接着502 Bad Gateway?
解决问题
线上问题排查常用命令?
1 | 1. jps 显示java进程,PS: Docker容器部署通过这个命令看是不准确的,最好可以通过启动日志查看服务状态。 |
排查过程
配置最大堆内存大小,设置oom日志;
- 观察启动后系统资源占用情况,如下图:
可见并无异常。
- 请求接口打印GC回收情况如下图:
可见FullGC回收频繁,这是导致系统卡顿的主要原因。观察内存震荡验证,如下图;代码原因,要么系统中处理了大量数据、要么系统中存在无法回收的资源,怎么确认?
等一会看下会不会资源回收,如果回收了就不是有不能回收的资源。过了一个观察内存回落如下图:
程序被我刷的卡死几次,为了截图我也不敢刷太厉害。凑合着看吧。
- 狂刷接口指导产生OOM,查看Dump文件如下图:
已产生dump文件:
dump文件概览:
堆文件:
分析OOM查看资源占用排名,优化高资源占用逻辑。
4.1 修改JSON转换逻辑,因为JSON转换中使用了大量的HashMap;
4.2 修改参数传递,因为参数大小影响循环线程栈的深度;
4.3 调整BigDecimal精度处理逻辑。再次运行观察资源占用,问题解决。如下图:
是否可以进一步优化?
新生代回收频繁,内存震荡严重?
加大新生代内存、设置最大最小内存减少震荡?
是否会导致增加GC回收时间?
是不是因为有临时的大对象?
分页减少临时的大数据量?
调整新生代到老年代的晋升年龄?
是否有大量的老年代数据?
增加老年代内存?
是否会引起更长的STW?到底怎么弄?
根据实际服务情况调整。