2011-03-24 61 views
1

我得到heap space错误,同时从数据库中写入大量数据的Excel工作表。 我不想使用JVM -XMX选项来增加内存。Java堆空间错误,OutOfMemory例外而写大数据的Excel工作表

以下是详细信息:

1)我使用org.apache.poi.hssf API 的Excel工作表的写作。

2)JDK 1.5版

3)的Tomcat 6.0

代码,我wriiten作品以及周边的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; 
      } 

     } 


    } 
+0

我已经搜索了堆空间错误很多人建议使用-Xmx选项增加JVM memoery。但是我有一些限制,所以不能以这种方式使用。 – PrashantK 2011-03-24 07:18:48

+0

@Suresh S如果超过23K不能工作,25K批次将不起作用。 – Thomas 2011-03-24 07:25:50

+0

@Prashank:好的,然后像每批20k一样做。 – 2011-03-24 07:31:50

回答

2

在开始写入excel之前,不需要填充内存中的完整列表,而需要修改代码以使得每个对象在从数据库中读取时写入文件的方式工作。看看这个question了解另一种方法。

+0

我无法立即将对象写入文件,因为我需要将对象与业务逻辑进行比较,这就是为什么我将这些对象保存在地图中的原因。我一次从数据库中获得一定数量的数据,例如200条记录,我需要处理这些记录,一旦完成,我可以发送一张地图写入文件。 – PrashantK 2011-03-25 11:46:36

0

嗯,我不知道,如果POI可以处理的增量更新,但如果因此你可能想要写说10000行的文件块。如果不是,则可能需要使用CSV(因此不需要格式化)或增加内存。

问题是,在写入文件完成之前(在所有行已生成并写入文件之前),您需要将对象写入文件,以便进行垃圾回收(不再有活动线程的引用)。

编辑:

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

+0

谢谢,第一点是相当不错的,我修改了代码后,使用一个对象(用于写入)我立即设置该obj =空值。我希望它能起作用。对于第二点,我在某些意义上的一些限制是,我获取一些记录处理业务逻辑中的这些记录,并将这些值设置为VO(值对象),这就是为什么我需要维护一个Map以便与之前的对象进行比较。 – PrashantK 2011-03-25 11:42:19

0

正如托马斯指出,你有太多的物体占用太多的空间,并需要一种方法来减少。有几个策略可以考虑:

  • 您是否需要在循环中每次创建一个新工厂,或者可以重新使用它吗?
  • 您可以从一个循环开始,获取您需要的信息到一个新的结构中,然后丢弃旧的结构?
  • 你可以将处理分割成一个线程链,发送信息到下一步,避免构建一个耗费大量内存的结构吗?