GPS設備定期發送數據至Redis,Redis做消息隊列,Java服務爲消費者,在while(true)中不斷的去消費數據,代碼如下:
while (true){
Object e = redisTemplate.opsForList().rightPop("list");
if(null==e) continue;
executor.execute(() -> {
dataDeal(e);
});
}
部署至生產環境運行了一段時間之後報異常:
[main] WARN org.springframework.context.support.AbstractApplicationContext 557 refresh - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataHandle': Invocation of init method failed;
nested exception is org.springframework.data.redis.RedisSystemException: Redis exception;
nested exception is io.lettuce.core.RedisException: java.lang.OutOfMemoryError: GC overhead limit exceeded
原因分析:
解決方案:解決中
- 查看CPU等系統信息
top
分核心查看
top -H
可以看到PID爲9763的進程佔了90%的cpu;查看該進程下比較耗費資源的線程
top -H -p 9763
找到幾個比較耗費資源的線程,jstack查看堆內存
jstack 9763 | grep 262b -A 20 -B 20
262b爲9771的16進制形式,-A 20 -B 20上下20行
- 查看dump文件
啓動時加入參數打印dump文件
nohup java -XX:+HeapDumpOnOutOfMemoryError -XX:+HeapDumpBeforeFullGC -XX:HeapDumpPath=./logs/ -jar gps_reader-0.0.1-SNAPSHOT.jar &
下載dump文件,導入Memory Analyzer分析,分析結果:
定位到發生問題的代碼位置: