Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java堆空间错误,将大数据写入excel工作表时OutofMemory异常_Java_Performance_Out Of Memory - Fatal编程技术网

Java堆空间错误,将大数据写入excel工作表时OutofMemory异常

Java堆空间错误,将大数据写入excel工作表时OutofMemory异常,java,performance,out-of-memory,Java,Performance,Out Of Memory,我在将大型数据从数据库写入excel工作表时遇到Java堆空间错误。 我不想使用JVM-XMX选项来增加内存 以下是详细信息: 1) 我正在使用org.apache.poi.hssf api 用于excel表格的书写 2) JDK版本1.5 3) Tomcat 6.0 我编写的代码在大约23000条记录中运行良好,但在超过23K条记录中失败 代码如下: ArrayList l_objAllTBMList= new ArrayList(); l_objAllTBMList = (Array

我在将大型数据从数据库写入excel工作表时遇到Java堆空间错误。 我不想使用JVM-XMX选项来增加内存

以下是详细信息:

1) 我正在使用org.apache.poi.hssf api 用于excel表格的书写

2) JDK版本1.5

3) Tomcat 6.0

我编写的代码在大约23000条记录中运行良好,但在超过23K条记录中失败

代码如下:

ArrayList l_objAllTBMList= new ArrayList();
    l_objAllTBMList = (ArrayList) m_objFreqCvrgDAO.fetchAllTBMUsers(p_strUserTerritoryId);
    ArrayList l_objDocList = new ArrayList();
    m_objTotalDocDtlsInDVL= new HashMap();
    Object l_objTBMRecord[] = null;
    Object l_objVstdDocRecord[] = null;
    int l_intDocLstSize=0;
    VisitedDoctorsVO l_objVisitedDoctorsVO=null;
    int l_tbmListSize=l_objAllTBMList.size();
    System.out.println(" getMissedDocDtlsList_NSM ");

        for(int i=0; i<l_tbmListSize;i++)
        {
            l_objTBMRecord = (Object[]) l_objAllTBMList.get(i);

            l_objDocList = (ArrayList) m_objGenerateVisitdDocsReportDAO.fetchAllDocDtlsInDVL_NSM((String) l_objTBMRecord[1], p_divCode, (String) l_objTBMRecord[2], p_startDt, p_endDt, p_planType, p_LMSValue, p_CycleId, p_finYrId);
            l_intDocLstSize=l_objDocList.size();
            try {
                    l_objVOFactoryForDoctors = new VOFactory(l_intDocLstSize, VisitedDoctorsVO.class); 

/* Factory class written to create and maintain limited no of Value Objects (VOs)*/

                } catch (ClassNotFoundException ex) {
                    m_objLogger.debug("DEBUG:getMissedDocDtlsList_NSM :Exception:"+ex);
                } catch (InstantiationException ex) {
                    m_objLogger.debug("DEBUG:getMissedDocDtlsList_NSM :Exception:"+ex);
                } catch (IllegalAccessException ex) {
                    m_objLogger.debug("DEBUG:getMissedDocDtlsList_NSM :Exception:"+ex);
                }


                for(int j=0; j<l_intDocLstSize;j++)
                {
                    l_objVstdDocRecord = (Object[]) l_objDocList.get(j);
                    l_objVisitedDoctorsVO = (VisitedDoctorsVO) l_objVOFactoryForDoctors.getVo();
                    if (((String) l_objVstdDocRecord[6]).equalsIgnoreCase("-"))
                    {
                        if (String.valueOf(l_objVstdDocRecord[2]) != "null")
                        {
                            l_objVisitedDoctorsVO.setPotential_score(String.valueOf(l_objVstdDocRecord[2]));
                            l_objVisitedDoctorsVO.setEmpcode((String) l_objTBMRecord[1]);
                            l_objVisitedDoctorsVO.setEmpname((String) l_objTBMRecord[0]);
                            l_objVisitedDoctorsVO.setDoctorid((String) l_objVstdDocRecord[1]);
                            l_objVisitedDoctorsVO.setDr_name((String) l_objVstdDocRecord[4] + " " + (String) l_objVstdDocRecord[5]);
                            l_objVisitedDoctorsVO.setDoctor_potential((String) l_objVstdDocRecord[3]);
                            l_objVisitedDoctorsVO.setSpeciality((String) l_objVstdDocRecord[7]);
                            l_objVisitedDoctorsVO.setActualpractice((String) l_objVstdDocRecord[8]);

                            l_objVisitedDoctorsVO.setLastmet("-");
                            l_objVisitedDoctorsVO.setPreviousmet("-");
                            m_objTotalDocDtlsInDVL.put((String) l_objVstdDocRecord[1], l_objVisitedDoctorsVO);
                        }

                    }

                }// End of While
               writeExcelSheet(); // Pasting this method at the end

            // Clean up code
            l_objVOFactoryForDoctors.resetFactory(); 
            m_objTotalDocDtlsInDVL.clear();// Clear the used map
            l_objDocList=null;
            l_objTBMRecord=null;
            l_objVstdDocRecord=null;

        }// End of While
        l_objAllTBMList=null;
        m_objTotalDocDtlsInDVL=null;

-------------------------------------------------------------------
private void writeExcelSheet() throws IOException
 {
        HSSFRow l_objRow = null;
        HSSFCell l_objCell = null;
        VisitedDoctorsVO l_objVisitedDoctorsVO = null;
        Iterator l_itrDocMap = m_objTotalDocDtlsInDVL.keySet().iterator();
        while (l_itrDocMap.hasNext())
        {
            Object key = l_itrDocMap.next();
            l_objVisitedDoctorsVO = (VisitedDoctorsVO) m_objTotalDocDtlsInDVL.get(key);
            l_objRow = m_objSheet.createRow(m_iRowCount++);

            l_objCell = l_objRow.createCell(0);
            l_objCell.setCellStyle(m_objCellStyle4);
            l_objCell.setCellValue(String.valueOf(l_intSrNo++));

            l_objCell = l_objRow.createCell(1);
            l_objCell.setCellStyle(m_objCellStyle4);
            l_objCell.setCellValue(l_objVisitedDoctorsVO.getEmpname() + " (" + l_objVisitedDoctorsVO.getEmpcode() + ")"); // TBM Name

            l_objCell = l_objRow.createCell(2);
            l_objCell.setCellStyle(m_objCellStyle4);
            l_objCell.setCellValue(l_objVisitedDoctorsVO.getDr_name());// Doc Name

            l_objCell = l_objRow.createCell(3);
            l_objCell.setCellStyle(m_objCellStyle4);
            l_objCell.setCellValue(l_objVisitedDoctorsVO.getPotential_score());// Freq potential score

            l_objCell = l_objRow.createCell(4);
            l_objCell.setCellStyle(m_objCellStyle4);
            l_objCell.setCellValue(l_objVisitedDoctorsVO.getDoctor_potential());// Freq potential score

            l_objCell = l_objRow.createCell(5);
            l_objCell.setCellStyle(m_objCellStyle4);
            l_objCell.setCellValue(l_objVisitedDoctorsVO.getSpeciality());//CP_GP_SPL

            l_objCell = l_objRow.createCell(6);
            l_objCell.setCellStyle(m_objCellStyle4);
            l_objCell.setCellValue(l_objVisitedDoctorsVO.getActualpractice());// Actual practise

            l_objCell = l_objRow.createCell(7);
            l_objCell.setCellStyle(m_objCellStyle4);
            l_objCell.setCellValue(l_objVisitedDoctorsVO.getPreviousmet());// Lastmet

            l_objCell = l_objRow.createCell(8);
            l_objCell.setCellStyle(m_objCellStyle4);
            l_objCell.setCellValue(l_objVisitedDoctorsVO.getLastmet());// Previousmet

        }
        // Write OutPut Stream
        try {
                out = new FileOutputStream(m_objFile);
                outBf = new BufferedOutputStream(out);
                m_objWorkBook.write(outBf);
            } catch (Exception ioe) {
            ioe.printStackTrace();
            System.out.println(" Exception in chunk write");
        } finally {
            if (outBf != null) {
                outBf.flush();
                outBf.close();
                out.close();

                l_objRow=null;
                l_objCell=null;
            }

        }


    }
ArrayList l_objAllTBMList=new ArrayList();
l_objAllTBMList=(ArrayList)m_objFreqCvrgDAO.fetchAllTBMUsers(p_strusterterritoryid);
ArrayList l_objDocList=新的ArrayList();
m_objTotalDocDtlsInDVL=新HashMap();
对象l_objTBMRecord[]=null;
对象l_objVstdDocRecord[]=null;
int l_intDocLstSize=0;
VisitedDoctorsVO l_objVisitedDoctorsVO=null;
int l_tbmListSize=l_objAllTBMList.size();
System.out.println(“getMissedDocDtlsList_NSM”);

对于(int i=0;i嗯,我不确定POI是否可以处理增量更新,但如果可以,您可能希望将10000行的数据块写入文件。如果不能,您可能需要使用CSV(因此无格式)或增加内存

问题是,在写入文件完成之前(在生成所有行并将其写入文件之前),需要使写入文件的对象可省略以进行垃圾收集(不再从活动线程引用)

编辑:


如果你能将较小的数据块写入文件,你也只需要从数据库中加载必要的数据块。因此,一次加载50000条记录,然后尝试写入10000条中的5条数据块是没有意义的,因为这50000条记录可能已经消耗了大量内存。

而不是在之前在内存中填充完整的列表e开始编写excel时,您需要修改代码,以便在从数据库中读取每个对象时将其写入一个文件中。看看这个,了解另一种方法。

正如Thomas指出的,您有太多的对象占用了太多的空间,需要一种方法来减少这种情况为此,我可以想到:

  • 您是否需要每次在循环中创建一个新工厂,或者您是否可以重用它
  • 你能从一个循环开始,把你需要的信息放到一个新的结构中,然后丢弃旧的结构吗
  • 您能否将处理拆分为一个线程链,将信息转发到下一步,从而避免构建一个占用大量内存的结构

我搜索了堆空间错误,很多人建议使用-Xmx选项增加JVM内存。但我有一些限制,因此无法使用这种方法。@Suresh S如果它在23K以上不起作用,那么25K批将不起作用。@Prashank:好的,然后像每个20k批一样进行操作。还有一个问题:有哪些限制阻止了你从增加内存开始?@Thomas我的代码将部署在客户端服务器上,我不能选择为我的代码增加内存。我认为作为一名程序员,我应该围绕我的代码进行工作。谢谢,第一点很好,我修改了代码,在使用一个对象之后(用于编写)我立即设置obj=null。我希望它能工作。对于第二点,我有一些限制,在某种意义上,我获取一些记录,在业务逻辑中处理这些记录,并将这些值设置为VOs(值对象)这就是为什么我需要维护一个映射,以便与以前的对象进行比较。我不能立即将对象写入文件,因为我需要与业务逻辑的对象进行比较,这就是为什么我将这些对象保存在映射中。我一次从数据库中获取200条记录之类的特定数据集,我需要处理这些记录,一旦完成,我可以发送映射到o写入文件。