背景
最近遇到一个网站,需要每日签到和做任务。由于麻烦,因此写了一个定时任务挂到自己一核2G的阿里云上。该任务基于xxl-job,有2个服务,一个是控制台admin服务,另一个是任务服务。
这个任务跑了一段时间正常之后我就没管了,有一天我看那个网站的积分怎么不动了,感到怀疑。登陆服务器一看,admin挂了。。。于是重启跑了一段时间,发现admin(以下用a服务表示)占用内存越来越多,遂怀疑是OOM了。
监控
由于一开始没有做监控,没有直接证据证明是OOM,说不定是别人关了呢?(由于借给别的朋友使用)
灵机一动,阿里云应该有监控,一看,果然有。如下图:
可以看到,每次启动a服务之后内存占用持续走高,挂掉的时候又一个突然的内存下降和CPU使用率100%。结合我之前遇到OOM的经验,果断猜测是堆栈满了,CPU一直跑GC导致的。
可是到此也只是有初步猜测。需要解决问题还需要更多的证据。
因此在启动脚本中添加监控参数:
- -XX:+PrintGC 打印GC日志
- -XX:+PrintHeapAtGC 在GC前后输出Heap信息
- -XX:+HeapDumpOnOutOfMemoryError OOM时输出日志
- -XX:HeapDumpPath=/*/heapdump.hprof 3输出日志的位置
- -XX:+UseSerialGC 使用单线程GC,因为只有一核,jdk8默认多线程垃圾回收器,没什么意义。考虑单线程回收效率高一点。
- -Xmx300m 不启动a服务的时候大概剩下500M空间,如果能收掉,300m应该就能收了。
- -Xloggc:/*/gc.log gc日志的输出位置
- -XX:+PrintGCDateStamps 输出gc时间
- -Xint 考虑到是不是因为定时调用导致编译机器码,所以强制走解释执行
以上参数也是考虑了一段时间和试错之后选定的。接下来就看下次的效果了。