jedis的hscan方法出现内存溢出问题
解决方法:
下面是我使用hscan方法错误的写法,使用了递归,数据大的时候导致java代码出现StackOverflow的内存溢出错误:
public boolean hscan(int dbIndex,String key,int pageSize){
Map<String, Integer> mapList=new HashMap<String, Integer>();
Jedis jedis = null;
try {
jedis = Redis.getJedis();
jedis.select(dbIndex);
ScanParams sp = new ScanParams();
sp.count(pageSize);//每次多少条
loop(mapList,key, jedis, "0", sp);
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());
return false;
}finally{
// 返还到连接池
if (jedis != null) {
jedis.close();
}
}
return true;
}
public void loop(Map<String, Integer> mapList,String key, Jedis jedis, String cursor,
ScanParams sp) {
try {
ScanResult<Entry<String, String>> map = jedis.hscan(key, cursor, sp);
cursor = map.getStringCursor();
for (Entry<String, String> en : map.getResult()) {
//业务代码
}
if (!"0".equals(cursor)) {
loop(mapList,key, jedis, cursor, sp);
}
} catch (Exception e) {
logger.error(e.getMessage());
e.printStackTrace();
}
}
正确方法:
public Map<String, Integer> getAll(String hashKey, int iterSize) {
Jedis jedis = null;
Map<String, Integer> mapList=new HashMap<String, Integer>();
try {
int cursor = 0;
ScanParams scanParams = new ScanParams().match("*").count(iterSize > 0 ? iterSize :
1000);
ScanResult<Entry<String, String>> scanResult;
jedis = Redis.getJedis();
jedis.select(0);
do {
scanResult = jedis.hscan(hashKey, String.valueOf(cursor), scanParams);
for (Entry<String, String> en : scanResult.getResult()) {
//业务代码
}
//获取游标位置,若大于0,则代表还有数据,需要继续迭代
cursor = Integer.parseInt(scanResult.getStringCursor());
} while (cursor > 0);
}catch (Exception e) {
logger.error(e.getLocalizedMessage(), e);
return null;
}finally{
// 返还到连接池
if (jedis != null) {
jedis.close();
}
}
return mapList;
}