什么!服务器内存又双叒叕打满了!
时间:2026-09-22 18:06 来源:未知 人气:
1、问题背景
深夜,小菜同学突然被一阵急促的报警声吵醒,原来是手机收到了一连串关于容器内存使用率过高的报警信息。赶紧打开电脑查看服务器状态,发现容器内存使用率持续高达99%,下面把排查的过程和分析记录下来,以供大家参考。
2、问题现象
接收到系统的报警后,小菜同学立即检查了容器状态,观察到以下现象:
- JVM堆内存使用率正常,在50%左右波动,在凌晨1点的时候年轻代使用无明显波动,老年代使用有直线上涨,但是执行了一次
Full GC(也可能是Major GC)后恢复了正常。 - 容器内存使用率在凌晨1点的时候有一个直线的上涨,并且随后一直保持在上涨后的水平。
服务使用的配置如下:
主要启动参数:-Xms4g -Xmx4g -Xmn2g -XX:+UseG1GC -XX:G1HeapRegionSize=8m -XX:G1ReservePercent=15 -XX:InitiatingHeapOccupancyPercent=50
容器配置:4C5G
3、定位原因
虽然容器内存已经使用了99%,但是JVM堆使用率在经过一次Full GC后已经降到了50%之后,所以并没有立马重启服务,还是先来看看造成Full GC的原因。
鉴于堆使用率已经恢复正常,查看当时的内存快照意义不大,因此决定首先从观察到的现象入手。因为凌晨1点的时候系统的流量不会很大,所以大概率是因为定时任务造成了,先排查报警服务凌晨1点执行的定时任务。幸运的是调度平台当时只有一个定时任务在执行,立马查看对应的逻辑,发现了以下代码片段中潜在的问题(简化之后):
public void job() {
// ... do business
int pageSize = 500;
while ( xxx ) {
// 每次查询500个订单
ListString orderNoList = orderService.getOrderPage(pageSize);
// 查询500个订单对应的账单
ListOrderBill orderBills = billService.findByOrderNos(orderNoList);
// ... do business
}
// ... do business
}