先简单介绍下项目:数据展示项目,合计有2千张页面,200多人使用,目前部分报表数据量较大,所以sql查询结果出来的也较慢。
jvm内存oom,jvm自己宕掉,怎么确定是oom导致的呢?
oom的几种表现形式:
1)tomcat的catalina.outh中有异常日志,如执行cat catalina.out | grep OutOf,有类似如下结果
22-Apr-2019 11:13:32.149 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -XX:+HeapDumpOnOutOfMemoryError
java.lang.OutOfMemoryError: GC overhead limit exceeded
Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded
2)如果catalina.sh配置了-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/boss/tomcat8/bin/dump.hprof 那么/home/boss/tomcat8/bin/路径下会有dump文件生成。
3)hs_err_pid21364.log ,有类似内容如下:
# Out of Memory Error (os_linux.cpp:2627), pid=30394, tid=140082987804416
解决oom的两个方向:
1)调整jvm的参数,首先尝试优化jvm各种参数,相信我,如果你不做任何配置,使用jvm的默认的回收策略,性能真的很差;
一个是合理设置jvm堆中eden、survior、old三个区的大小。
二是制定合理的回收策略,包括回收器、回收参数配置。jvm参数配置可参考:
三 配置dump路径,日志等,有问题便于定位和处理
四 JIT相关参数配置,最大化代码执行速度
https://blog.csdn.net/h2604396739/article/details/87778753
2)修改代码,减少代码中对象的生成,减少对象对内存的占用。
包括缓存,大的对象等,大的sql查询结果的处理等,可参考,https://blog.csdn.net/h2604396739/article/details/90600637
如下面的代码一次就声明了2G的空间的字节数组,新生代的eden和survior都放不下,直接放到老年代,会直接消耗很大的内存。
byte b[] = new byte[2*1024*1024*1024];
补充说明:
1)上面两种方案,应该先尝试修改jvm的参数,一般参数修改后就能解决oom的问题,如果还不行就需要修改代码了。
2)上面优化oom,大量减少缓存,导致的结果就是会增大数据库的压力、同时延长单个tomcat请求的占用时间,需要注意mysql压力变化(调整数据库连接池)和tomcat 连接配置(即server.xml中的connector)是否需要优化。或者根据你的系统分析会增加声明别的压力。
服务假死
完成上面的优化后,程序依然会挂掉,而且更频繁,现象:
发生时间:大概重启3小时左右,上午11点,下午2点多,都是系统使用较多的时间。最严重的一天挂了三次
用ps -ef | grep tomcat指令查看,发现tomcat的进程还在,端口也在占用。
但是日志不再打印,并且不再提供任何服务。这种情况其实是tomcat假死。
下面给出程序宕机和重启的时间的日志。
tomcat假死前的最后两条日志:时间-2019-05-28 14:10:19
[INFO]-[2019-05-28 14:10:19]-[info.info():50]-[http-nio-8080-exec-10] Takes:2315 ms [org.cboard.services.DataProviderService.queryAggData(Long,Map,Long,AggConfig,boolean)]
[INFO]-[2019-05-28 14:10:19]-[info.info():50]-[http-nio-8080-exec-10] Takes:2320 ms [org.cboard.controller.DashboardController.getAggregateData(Long,String,Long,String,Boolean)]
tomcat重启的最开始两条日志:时间-28-May-2019 14:18:10.173
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=128M; support was removed in 8.0
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=256m; support was removed in 8.0
28-May-2019 14:18:10.173 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version: Apache Tomcat/8.5.31
很懵逼,程序宕掉的时候没有记录任何错误日志。
没办法只能临时kill掉进程 然后重启tomcat。这里给出一个解决该问题的临时方案,linux定时任务脚本监控,发现程序假死时重启,参考脚本:https://blog.csdn.net/h2604396739/article/details/90736569
然后就需要定位tomcat假死原因了。
下面的博客继续介绍程序假死解决方案:https://blog.csdn.net/h2604396739/article/details/91375949