自己挖的坑自己填--JVM报内存溢出
在写定时任务时,对表数据进行批量操作,测试数据有10万条左右,在测试时发现跑着跑着出现内存溢出现象,最后发现创建的对象paramList 和tmBeanList没有被回收,经过资料查找,发现是循环内不要不断创建对象引用,不然有count次循环,内存中就有count份对象引用存在,就耗费内存了,所以每次循环完都得对对象引用进行销毁(设置为null);或直接在for循环体外声明对象,在循环体内创建对象的引用,这样内存中只有一份对象引用,每次new对象时,对象引用指向不同,但内存中只有一份。
/** * 定时任务,xxxx * @author xxx * @date xxx * @version xxx */ @Component(value = "xxxJob") public class xxxJob { @Transactional public void doService(Map<String, Object> scheduleJob) { logger.info("------------开始定时任务,xxxxx----------"); // 业务逻辑 ---省略业务代码--- for (Map<String, Object> map : list) { try { ---省略业务代码--- List<Map<String, Object>> tmBeanList = tMemberRfmDao.queryBeanForMap(tmr); List<Map<String, Object>> paramList = new ArrayList<>(); if (!CollectionUtils.isEmpty(tmBeanList)) { ---省略业务代码--- for (Map<String, Object> member : tmBeanList) { String memberId = (String) member.get("member_id"); Map<String, Object> tml = new HashMap<>(); ---省略业务代码--- tml.put("data_status", 0); tml.put("create_time", DateUtils.getDate("yyyy-MM-dd HH:mm:ss")); tml.put("update_time", DateUtils.getDate("yyyy-MM-dd HH:mm:ss")); paramList.add(tml); if(paramList.size() == INT_TWO_THOUSAND){ tMemberLabelDao.saveBatch(paramList); paramList.clear(); } } if(paramList.size() != 0){ tMemberLabelDao.saveBatch(paramList); } paramList = null; tmBeanList = null; ---日志--- }else{ ---日志--- } } catch (Exception e) { ---异常--- } } logger.info("------------结束定时任务,xxxx"); } }
备注(循环外声明对象,循环体内创建对象引用,Object对象引用指向不同的Object):
Object object = null;
for(int i = 0;i <=count; i++){
object = new Object();
}
作者:huangrenhui
欢迎任何形式的转载,但请务必注明出处。
如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【码猿手】。
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【码猿手】。
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。