背景: 在发布新功能到生产环境,系统突然不稳定了,过一会就会出现
GC overhead limit exceeded
这个问题,内存溢出,然后系统无法访问,最终通过排查,解决了内存溢出问题,特此记录
一、为什么会产生GC overhead limit exceeded问题
经过网上查询和总结,一般来说,有以下几点:
1. 程序中大量的死循环或有使用大内存的代码;
2. 程序中的递归栈的层数太深了,导致内存不足;
3. 给服务器的堆内存设置的太小,没有足够的内存可以使用;
4.这个是本次遇到的问题:数据库中的数据表数据太大,由于没有判断带有条件,导致查询全表数据,查询出来的数据量太大,内存溢出;
二、PostgreSQL数据库的报错问题:
使用的是postgres数据库,所以具体的报错为:Ran out of memory retrieving query results.
这个错误就是表示一次查询的数据太多,造成内存溢出。
所以,如果使用postgres数据库出现这个错误,有以下的解决方案:
(1) 使用分页查询或者条件查询
(2) 使用原生的jdbc驱动取查询数据
三、记录本次问题的解决方案
- 第一次出现的是全表查询,然后会出现内存溢出的错误,然后修改查询sql,带上条件进行查询,sql后面加上
where
条件 - 经过重新发布,系统依然不稳定,虽然改为了条件查询,但是好像还是会过一段时间就出现内存溢出,导致无法反问,这次发现查询该表的数据时,竟然是
数据库链接超时
,配置中配置的是60秒才链接超时,查询一下数据竟然这么慢,原因是: 数据库查询数据太慢,导致数据库连接被占用完(每次都要查询这个表),所以,解决方案就是:给这个表中where后面带有条件的字段加上索引!
即可。
这个问题上次已经遇到过一次,数据表的数据量太大,导致数据库查询不到数据,造成系统无法访问,所以,在查询大数据量表的时,全表查询一定要在sql带上条件或者分页,带有条件查询的,一定要在条件的字段上面加上索引~
切记!