合作机构:阿里云 / 腾讯云 / 亚马逊云 / DreamHost / NameSilo / INWX / GODADDY / 百度统计
深夜,小菜同学突然被一阵急促的报警声吵醒,原来是手机收到了一连串关于容器内存使用率过高的报警信息。赶紧打开电脑查看服务器状态,发现容器内存使用率持续高达99%,下面把排查的过程和分析记录下来,以供大家参考。
接收到系统的报警后,小菜同学立即检查了容器状态,观察到以下现象:
Full GC(也可能是Major GC)
后恢复了正常。服务使用的配置如下:
主要启动参数:-Xms4g -Xmx4g -Xmn2g -XX:+UseG1GC -XX:G1HeapRegionSize=8m -XX:G1ReservePercent=15 -XX:InitiatingHeapOccupancyPercent=50
容器配置:4C5G
虽然容器内存已经使用了99%,但是JVM堆使用率在经过一次Full GC
后已经降到了50%之后,所以并没有立马重启服务,还是先来看看造成Full GC
的原因。
鉴于堆使用率已经恢复正常,查看当时的内存快照意义不大,因此决定首先从观察到的现象入手。因为凌晨1点的时候系统的流量不会很大,所以大概率是因为定时任务造成了,先排查报警服务凌晨1点执行的定时任务。幸运的是调度平台当时只有一个定时任务在执行,立马查看对应的逻辑,发现了以下代码片段中潜在的问题(简化之后):
public void job() {
// ... do business
int pageSize = 500;
while ( xxx ) {
// 每次查询500个订单
List<String> orderNoList = orderService.getOrderPage(pageSize);
// 查询500个订单对应的账单
List<OrderBill> orderBills = billService.findByOrderNos(orderNoList);
// ... do business
}
// ... do business
}
TOP