清除list或者map集合,减少内存的占用率

Posted 唯一

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了清除list或者map集合,减少内存的占用率相关的知识,希望对你有一定的参考价值。

1.在编写程序对数据处理的时候我们经常会使用到list和map集合,有些时候我们存到集合里的数据只是暂时性的,在验证完或者使用完之后尽量对list或者map清空,及list.clear()后者map.clear(),

这样我们可以大大减轻服务器内存被占用率,特别是处理数据量比较大的验证以及过滤的时候,对于程序的性能以及运行速度都是影响很大的。

2.程序中我们经常会遇见把数据存到excel中然后经过中间件进入数据库中,这样的数据需要经过一系列的验证到最后只是把正确的数据保存到数据库中,错误的直接过滤掉,而经过验证的时候我们难免会遇见本身重复校验这块,比如你导入1W条数据,而我们比对是不是拿其中一个和剩下所有的比较,不重复了保存到一个集合中,重复的保存到一个集合中,这样有没有考虑到比对的次数?1W*1W是什么概念?上亿次呢,所以同样是写程序有的人写出来的代码运行速度很快,而有的人写的代码程序运行很慢,虽然功能都能实现,但是在数据量大的时候二者谁优谁劣就见分晓了。

3.例子:以下举一个简单的例子,写在这里以后没事的时候看看,同时提醒自己和大家写程序要养成一个良好的习惯,这点很重要。

    //批量导入学生信息
    public String batchImport(){
        long startTime = System.currentTimeMillis();
        SchoolInfoDTO school = (SchoolInfoDTO) request.getSession().getAttribute("schoolInfo");
        //文件导入失败
        if(filePath==null){
            request.setAttribute("msg", "请先选择要导入数据的文件!");
        }else{
            try {
                /**
                 * 1、读取Excel中的数据
                 */
                long t1 = System.currentTimeMillis();
                HashMap<String, ArrayList<Ac56TempDTO>> resultMap = readXls(filePath);
                long t2 = System.currentTimeMillis();
                System.out.println("---------------------------------------------------------------------------");
                System.out.println("Excel读取时间:"+(t2-t1)/1000+"秒");
                System.out.println("---------------------------------------------------------------------------");
                if(null==resultMap){
                    request.setAttribute("msg", "导入文件存在问题,请确认文件格式是否正确!");
                }else{
                    List<Ac56TempDTO> rightList = resultMap.get("right");
                    List<Ac56TempDTO> wrongList = resultMap.get("wrong");
                    int totalCount = (rightList==null?0:rightList.size()) + (wrongList==null?0:wrongList.size());
                    if(totalCount>5000){ //控制excel数据的数量
                        request.setAttribute("msg", "一次最多导入5000条数据。当前导入的数据大于5000条,请分多次导入!");
                    }else{
                        List<Ac56TempDTO> resultList = new ArrayList<Ac56TempDTO>();//待保存到数据库里的结果集
                        /**
                         * 2、删除ac56temp临时表中的数据
                         */
                        long t3=System.currentTimeMillis();
                        ac56Tempvs.deleteAc56TempTA(school.getAab001());
                        long t4=System.currentTimeMillis();
                        System.out.println("---------------------------------------------------------------------------");
                        System.out.println("删除数据时间:"+(t4-t3)/1000+"秒");
                        System.out.println("---------------------------------------------------------------------------");
                        /**
                         * 3、将不符合Excel填写规范的数据放入结果集中并清除内存中的错误格式数据
                         */
                        resultList.addAll(wrongList);
                        wrongList.clear();
                        /**
                         * 4、获取重复数据并放入removeUsers结果集,然后放入resultList结果集,然后清除removeUsers以及内存中的removeUsers对象
                         */
                        long t5=System.currentTimeMillis();
                        List<Ac56TempDTO> removeUsers = duplicateList(rightList);
                        resultList.addAll(removeUsers);//把重复的数据添加到结果集里面去
                        rightList.removeAll(removeUsers);//正确数据集合中剔除数据重复的集合  剩余的即是正确的数据
                        removeUsers.clear();//清除removeUsers以及内存中的removeUsers对象
                        long t6=System.currentTimeMillis();
                        System.out.println("---------------------------------------------------------------------------");
                        System.out.println("取出重复数据时间:"+(t6-t5)/1000+"秒");
                        System.out.println("---------------------------------------------------------------------------");
                        /**
                         * 5、判断年级和对应班级在本校是否存在,如果不存在,则记录下来放入resultList中,然后清除rightList中的list1和内存中的list1以及相关的map
                         */
                        long nb=System.currentTimeMillis();
                        //将年级和班级作为key,获取学校下的班级年级信息
                        HashMap<String, String> gradeClassName = new HashMap<String, String>();
                        for(Ac56TempDTO dto:rightList){
                            gradeClassName.put(dto.getBac053()+","+dto.getBac054(), school.getAab001());
                        }
                        //根据年级、班级和学校编号查询年级班级信息
                        HashMap<String, String> ac56Map = ac56vs.isGradeAndClassEmpty(gradeClassName);
                        List<Ac56TempDTO> list1 = new ArrayList<Ac56TempDTO>();
                        for(Ac56TempDTO dto:rightList){
                            String key = dto.getBac053()+","+dto.getBac054();
                            if(ac56Map.containsKey(key)&&"0".equals(ac56Map.get(key))){
                                dto.setDatastate("0");
                                dto.setErrormsg("年级和对应班级在本校中不存在!");
                                list1.add(dto);
                            }
                        }
                         //将年级和对应班级不存在的记录更新放到结果集中resultList,同时,清除rightList中的list1和内存中的list1以及相关的map
                        resultList.addAll(list1);
                        rightList.removeAll(list1);
                        list1.clear();
                        gradeClassName.clear();
                        ac56Map.clear();
                        long bj=System.currentTimeMillis();
                        System.out.println("----------------------------------------------------------------");
                        System.out.println("年级班级检查耗时:"+(bj-nb)/1000+"秒");
                        System.out.println("----------------------------------------------------------------");
                        /**
                         * 6、验证学生是否已经在学校网上办事系统中参保登记了
                         */
                        long t7=System.currentTimeMillis();
                        List<Ac56TempDTO> studentList = new ArrayList<Ac56TempDTO>();
                        for(Ac56TempDTO dto:rightList){
                            List<Ac56> ac56List= ac56vs.isStudentEmpty(dto.getAac002());
                            if(ac56List.size()>0){
                                String  aab004 =  ac56List.get(0).getAab004();
                                aab004 = aab004.substring(0, aab004.indexOf("("));
                                dto.setErrormsg("该生已在"+aab004+"进行了参保登记");
                                dto.setDatastate("0");
                                studentList.add(dto);
                            }
                        }
                        resultList.addAll(studentList);
                        rightList.removeAll(studentList);
                        studentList.clear();
                        long t8=System.currentTimeMillis();
                        System.out.println("-------------------------------------------------------------");
                        System.out.println("验证网上办事参保登记学生情况用时:"+(t8-t7)/1000+"秒");
                        System.out.println("-------------------------------------------------------------");
                        /**
                         * 7、查看此学生在ahsimis.ac02中是否有除了居民医保以外的正在参保的记录,有这样的学生,要记录下来放入oldList中
                         */
                        long t9=System.currentTimeMillis();
                        List<Ac56TempDTO> oldList = checkAC01(rightList);
                        resultList.addAll(oldList);
                        rightList.removeAll(oldList);
                        oldList.clear();
                        long t10  =System.currentTimeMillis();
                        System.out.println("--------------------------------------------------------------");
                        System.out.println("ESB耗时:"+(t10-t9)/1000+"秒");
                        System.out.println("--------------------------------------------------------------");
                        /**
                         * 导入结束
                         */
                        if(resultList.size()>0){
                            int count=0;
                            /*记录正确的数据条数*/
                            for(int i=0;i<resultList.size();i++){
                                if("1".equals(resultList.get(i).getDatastate())){
                                    count++;
                                }
                            }
                            long t11  =System.currentTimeMillis();
                            ac56Tempvs.insertStudent(resultList);
                            long t12  =System.currentTimeMillis();
                            System.out.println("--------------------------------------------------------------");
                            System.out.println("插入数据库耗时:"+(t12-t11)/1000+"秒");
                            System.out.println("--------------------------------------------------------------");
                            request.setAttribute("msg", "导入完成!共导入"+resultList.size()+"条数据,其中正确数据"+ count +"条。");
                        }else{
                            request.setAttribute("msg", "无数据,请核对表格!");
                        }
                    }
                }
            } catch (Exception e) {
                request.setAttribute("msg", "导入学生信息出错,请检查文件数据格式是否与给定的模板完全一致!");
                e.printStackTrace();
            }
        }
        long endTime = System.currentTimeMillis();
        System.out.println("--------------------------------------------------------------");
        System.out.println("导入总耗时:"+(endTime-startTime)/1000+"秒");
        return SUCCESS;
    }

 

    /**
     * 查找重复数据
     * @param alist:待去重对象
     * @return:返回重复的list
     */
    public  ArrayList<Ac56TempDTO> duplicateList(List<Ac56TempDTO> alist) {
        HashMap<String, String> map = new HashMap<String, String>();
        ArrayList<Ac56TempDTO>  duplicateList =new ArrayList<Ac56TempDTO>();
        //判断身份证号是否重复,如果重复了,就给相应的key赋aac002值,否则赋空值
        for(int i=0;i<alist.size();i++){
            String aac002 = alist.get(i).getAac002();
            if(map.containsKey(aac002)){
                map.put(aac002, aac002);
            }else{
                map.put(aac002, "");
            }
        }
        //取出身份证号重复的list集合
        for(int i=0;i<alist.size();i++){
            Ac56TempDTO dto =alist.get(i);
            if(map.containsValue(dto.getAac002())){
                dto.setDatastate("0");
                dto.setErrormsg("该身份证号重复出现多次!");
                duplicateList.add(dto);//里面放的都是数据重复的集合
            }
        }
        map.clear();
        return duplicateList;
    }

 

 

    /**
     * 读取Excel文件
     * @param path
     * @return List<Ac56TempDTO>
     * @throws Exception
     */
    private HashMap<String,ArrayList<Ac56TempDTO>> readXls(File path) throws Exception {
        SchoolInfoDTO school = (SchoolInfoDTO) request.getSession().getAttribute("schoolInfo");
        InputStream is = new FileInputStream(path);
        HSSFWorkbook hssfWorkbook = new HSSFWorkbook(is);
        Ac56TempDTO dto = null;
        ArrayList<Ac56TempDTO> rightList = new ArrayList<Ac56TempDTO>();
        ArrayList<Ac56TempDTO> wrongList = new ArrayList<Ac56TempDTO>();
        HashMap<String,ArrayList<Ac56TempDTO>> resultMap = new HashMap<String,ArrayList<Ac56TempDTO>>();
        // 读取工作表Sheet
        HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(0);
        if (hssfSheet == null) {
            return null;
        }
        int totalRows = hssfSheet.getPhysicalNumberOfRows()-1;
        // 循环行Row
        for (int rowNum = 1; rowNum <=totalRows ; rowNum++) {
            HSSFRow hssfRow = hssfSheet.getRow(rowNum);
            if (hssfRow == null)continue;
            dto = new Ac56TempDTO();
            //0姓名
            HSSFCell xm = hssfRow.getCell(0);
            dto.setAac003(ExcelUtils.getValue(xm));
            //1身份证:因为可能包含小写字母x,必须转换成大写的X
            HSSFCell sfz = hssfRow.getCell(1);
            String aac002 = ExcelUtils.getValue(sfz);
            if(!"".equals(StringUtils.ObjectToString(aac002))){
                aac002 = aac002.toUpperCase();
            }
            dto.setAac002(aac002);
            //2个人身份
            HSSFCell grsf = hssfRow.getCell(2);
            dto.setAac012(ExcelUtils.getValue(grsf));
            //3所在年级
            HSSFCell sznj = hssfRow.getCell(3);
            dto.setBac053(ExcelUtils.getValue(sznj));
            //4所在班级
            HSSFCell szbj = hssfRow.getCell(4);
            dto.setBac054(ExcelUtils.getValue(szbj));
            //5家庭联系电话
            HSSFCell lxdh = hssfRow.getCell(5);
            dto.setAae005(ExcelUtils.getValue(lxdh));
            //6低保标识
            HSSFCell db = hssfRow.getCell(6);
            dto.setBac048(ExcelUtils.getValue(db));
            //7残疾标识
            HSSFCell cjbs = hssfRow.getCell(7);
            dto.setBac049(ExcelUtils.getValue(cjbs));
            //8大病标识
            HSSFCell dbbs = hssfRow.getCell(8);
            dto.setBac041(ExcelUtils.getValue(dbbs));
            //9三无标识
            HSSFCell swbs = hssfRow.getCell(9);
            dto.setBac042(ExcelUtils.getValue(swbs));
            //默认添加字段:单位编号、缴费方式
            dto.setAab001(school.getAab001());
            dto.setBac044("3");
            /*只要身份证号为空,就退出循环*/
            if("".equals(StringUtils.ObjectToString(dto.getAac002()))){
                break;
            }else {
                if((dto.getAac002().length() !=18) ||!CardUtils.isValidate18Idcard(dto.getAac002())){
                     //身份证合法性验证1
                     dto.setErrormsg("身份证号不合法,必须为18位的有效身份证号");
                     dto.setDatastate("0");
                     wrongList.add(dto);
                 }else if("".equals(dto.getAac012())||(!"92".equals(dto.getAac012())&&!"94".equals(dto.getAac012()))){
                     dto.setErrormsg("个人身份必须为92或94");
                     dto.setDatastate("0");
                     wrongList.add(dto);
                 }else if("".equals(dto.getBac053())||dto.getBac053().length()>20){
                     dto.setErrormsg("年级不能为空,且长度不能大于20");
                     dto.setDatastate("0");
                     wrongList.add(dto);
                 }else if("".equals(dto.getBac054())||dto.getBac054().length()>20){
                     //所在班级不能为空
                     dto.setErrormsg("班级不能为空,且长度不能大于20");
                     dto.setDatastate("0");
                     wrongList.add(dto);
                 }else if("".equals(dto.getAae005())||dto.getAae005().length()>20){
                     //家庭联系电话长度不能大于20
                     dto.setErrormsg("家庭联系电话不能为空,且长度不能大于20");
                     dto.setDatastate("0");
                     wrongList.add(dto);
                 }else if(!"0".equals(dto.getBac048())&&!"1".equals(dto.getBac048())){
                     //低保标识:0否,1是
                     dto.setErrormsg("低保标识只能填0或1");
                     dto.setDatastate("0");
                     wrongList.add(dto);
                 }else if(!"0".equals(dto.getBac049())&&!"1".equals(dto.getBac049())){
                     //残疾标识:0否,1是
                     dto.setErrormsg("残疾标识只能填0或1");
                     dto.setDatastate("0");
                     wrongList.add(dto);
                 }else if(!"0".equals(dto.getBac041())&&!"1".equals(dto.getBac041())){
                     //大病标识:0否,1是
                     dto.setErrormsg("大病标识只能填0或1");
                     dto.setDatastate("0");
                     wrongList.add(dto);
                 }else if(!"0".equals(dto.getBac042())&&!"1".equals(dto.getBac042())){
                     //三无标识:0否,1是
                     dto.setErrormsg("三无标识只能填0或1");
                     dto.setDatastate("0");
                     wrongList.add(dto);
                 }else{
                     rightList.add(dto);
                 }
            }
        }
        resultMap.put("right", rightList);
        resultMap.put("wrong", wrongList);
        return resultMap;
    }

 

以上是关于清除list或者map集合,减少内存的占用率的主要内容,如果未能解决你的问题,请参考以下文章

电脑内存占用率多少算是太高

cgi/fastcgi占用率高

为啥调用 std:map:clear 后内存占用率没有降低

性能测试指标及解释

错误记录SeeMusic 内存错误 ( 内存占用率 100 % | 清除系统设置信息 )

cpu占用率