java8 lambda表达式导致 java.lang.OutOfMemoryError: Java heap space 问题

最近开发商品同步功能。遇到 java.lang.OutOfMemoryError: Java heap space 问题,
在本机和同事电脑上跑程序,都没问题。30w条数据,单线程跑大概2个小时跑完。但是放到服务器上面跑 就挂了。每次在服务器上跑到大概 1/3的时候就抛出 java.lang.OutOfMemoryError: Java heap space 异常!
同步打代码如下:

public boolean syncProd2GoodsCallBack(List goodsCeneterProdVoList) {
        if(goodsCeneterProdVoList != null && goodsCeneterProdVoList.size() > 0){
            // 取出所有商品ID
            List goodsIds = new ArrayList<>();
            goodsCeneterProdVoList.stream().forEach(vo->{
                goodsIds.add(vo.getProdId());
            });
            // 获取已存在的商品列表
            List existList = tbGoodsMapper.getExistGoodsList(goodsIds);
            Map existGoodsMap = existList.stream().collect(Collectors.toMap(TbGoods::getGoodsId, Function.identity(), (key1, key2) -> key2));

            //获取已存在的图片列表
            List existPicList =  tbGoodsPictureMapper.getExistPictureList(goodsIds);
            Map existPicMap = existPicList.stream().collect(Collectors.toMap(TbGoodsPicture::getGoodsPictureId,Function.identity(), (key1, key2) -> key2));

            // 图片list
            List pictureList = new ArrayList<>();
            List goodsList  = goodsCeneterProdVoList.stream().map(goodsCeneterProdVo -> {
                TbGoods goods = existGoodsMap.get(goodsCeneterProdVo.getProdId());
                if(BeanUtil.isEmpty(goods)){
                    goods = new TbGoods();
                }
                BeanUtil.copyPropertiesIgnoreNull(goodsCeneterProdVo,goods);
                goods.setGoodsId(goodsCeneterProdVo.getProdId());
                goods.setPlatformAuthFlag(StrUtil.isEmpty(goods.getPlatformAuthFlag()) ? "0" :goods.getPlatformAuthFlag() );
                goods.setApprovalNumber(StrUtil.isEmpty(goods.getApprovalNumber())?" ":goods.getApprovalNumber());

                List pictures = goodsCeneterProdVo.getProdPictureList();
                // 每个商品的图片数据
                List picList;
                if(pictures !=null && pictures.size() > 0){
                    picList =   pictures.stream().map(picVo->{
                        TbGoodsPicture picture = existPicMap.get(picVo.getProdPictureId()) ;
                        if(BeanUtil.isEmpty(picture)){
                            picture = new TbGoodsPicture();
                        }
                        BeanUtil.copyPropertiesIgnoreNull(picVo,picture);
                        picture.setGoodsId(picVo.getProdId());
                        picture.setGoodsPictureId(picVo.getProdPictureId());
                        return  picture;
                    }).collect(Collectors.toList());
                    pictureList.addAll(picList);
                    picList.clear();
                }
                pictures.clear();
                return goods;
            }).collect(Collectors.toList()) ;
            if(goodsList != null && goodsList.size() > 0){
                tbGoodsMapper.saveOrUpdateBatch(goodsList);
            }
            if(pictureList !=null && pictureList.size() > 0){
                tbGoodsPictureMapper.saveOrUpdateBatch(pictureList);
            }
            // 使用完之后 及时释放
            goodsList.clear();
            pictureList.clear();
            existList.clear();
            existGoodsMap.clear();
            existPicList.clear();
            existPicMap.clear();
            goodsIds.clear();
        }
        return true;
    }

纠结了很久,一点点的优化 ,从开始在遍历里面查询单个商品是否存在,到先把所有存在商品查出来,到从list查找换成map查找。到最后,每个list 和map使用完之后就clear掉。都不行!
部署到服务器跑到 1/3左右就挂了。
后来 我组长将 .stream().map()..collect(Collectors.toList()) 换成** .forEach() **,再放到服务器上居然跑成功了。修改后的代码如下:

public boolean syncProd2GoodsCallBack(List goodsCeneterProdVoList) {
        if(goodsCeneterProdVoList != null && goodsCeneterProdVoList.size() > 0){
            // 取出所有商品ID
            List goodsIds = new ArrayList<>();
            goodsCeneterProdVoList.stream().forEach(vo->{
                goodsIds.add(vo.getProdId());
            });
            // 获取已存在的商品列表
            List existList = tbGoodsMapper.getExistGoodsList(goodsIds);
            Map existGoodsMap = existList.stream().collect(Collectors.toMap(TbGoods::getGoodsId, Function.identity(), (key1, key2) -> key2));

            //获取已存在的图片列表
            List existPicList =  tbGoodsPictureMapper.getExistPictureList(goodsIds);
            Map existPicMap = existPicList.stream().collect(Collectors.toMap(TbGoodsPicture::getGoodsPictureId,Function.identity(), (key1, key2) -> key2));

            // 图片list
            List pictureList = new ArrayList<>();
            List goodsList = new ArrayList<>();
            goodsCeneterProdVoList.forEach(goodsCeneterProdVo->{
                TbGoods goods = existGoodsMap.get(goodsCeneterProdVo.getProdId());
                if(BeanUtil.isEmpty(goods)){
                    goods = new TbGoods();
                }
                BeanUtil.copyPropertiesIgnoreNull(goodsCeneterProdVo,goods);
                goods.setGoodsId(goodsCeneterProdVo.getProdId());
                goods.setPlatformAuthFlag(StrUtil.isEmpty(goods.getPlatformAuthFlag()) ? "0" :goods.getPlatformAuthFlag() );
                goods.setApprovalNumber(StrUtil.isEmpty(goods.getApprovalNumber())?" ":goods.getApprovalNumber());

                List pictures = goodsCeneterProdVo.getProdPictureList();
                // 每个商品的图片数据
                List picList = new ArrayList<>();
                if(pictures !=null && pictures.size() > 0){
                    pictures.forEach(picVo->{
                        TbGoodsPicture picture = existPicMap.get(picVo.getProdPictureId()) ;
                        if(BeanUtil.isEmpty(picture)){
                            picture = new TbGoodsPicture();
                        }
                        BeanUtil.copyPropertiesIgnoreNull(picVo,picture);
                        picture.setGoodsId(picVo.getProdId());
                        picture.setGoodsPictureId(picVo.getProdPictureId());
                        pictureList.addAll(picList);
                    });
                    picList.clear();
                }
                pictures.clear();
                goodsList.add(goods);
            });
            if(goodsList != null && goodsList.size() > 0){
                tbGoodsMapper.saveOrUpdateBatch(goodsList);
            }
            if(pictureList !=null && pictureList.size() > 0){
                tbGoodsPictureMapper.saveOrUpdateBatch(pictureList);
            }
            // 使用完之后 及时释放
            goodsList.clear();
            pictureList.clear();
            existList.clear();
            existGoodsMap.clear();
            existPicList.clear();
            existPicMap.clear();
            goodsIds.clear();
        }
        return true;
    }

在此记录一下,可能原因:用stream().map()..collect(Collectors.toList()) 对内存消耗大一些!

你可能感兴趣的:(java8 lambda表达式导致 java.lang.OutOfMemoryError: Java heap space 问题)