2013-09-06 3 views
3

Я новичок в java. Я просто пытаюсь понять, как бороться с переполнением памяти кучи и ее причинами. Может кто-нибудь, пожалуйста, помогите мне в нижнем коде, почему он бросает эту ошибку. и как я мог избежать этого.из памяти кучи, java

ошибка:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:2361) at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:117) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:406) at java.lang.StringBuffer.append(StringBuffer.java:237) at com.ugam.qa.tittle.XlsxToCsv.xlsx(XlsxToCsv.java:49) at com.ugam.qa.tittle.XlsxToCsv.main(XlsxToCsv.java:77)

package com.ugam.qa.tittle; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.util.Iterator; 

import org.apache.poi.ss.usermodel.Cell; 
import org.apache.poi.ss.usermodel.Row; 
import org.apache.poi.xssf.usermodel.XSSFSheet; 
import org.apache.poi.xssf.usermodel.XSSFWorkbook; 

public class XlsxToCsv { 

    static void xlsx(File inputFile, File outputFile) { 
     // For storing data into CSV files 
     StringBuffer data = new StringBuffer(); 

     try { 
      FileOutputStream fos = new FileOutputStream(outputFile); 
      // Get the workbook object for XLSX file 
      XSSFWorkbook wBook = new XSSFWorkbook(new FileInputStream(inputFile)); 
      // Get first sheet from the workbook 
      XSSFSheet sheet = wBook.getSheetAt(0); 
      Row row; 
      Cell cell; 
      // Iterate through each rows from first sheet 
      Iterator<Row> rowIterator = sheet.iterator(); 

      while (rowIterator.hasNext()) { 
       row = rowIterator.next(); 
       { 
       // For each row, iterate through each columns 
       Iterator<Cell> cellIterator = row.cellIterator(); 
       while (cellIterator.hasNext()) { 

        cell = cellIterator.next(); 

        switch (cell.getCellType()) { 
         case Cell.CELL_TYPE_BOOLEAN: 
          data.append(cell.getBooleanCellValue() + ","); 

          break; 
         case Cell.CELL_TYPE_NUMERIC: 
          data.append(cell.getNumericCellValue() + ","); 

          break; 
         case Cell.CELL_TYPE_STRING: 
          data.append(cell.getStringCellValue() + ","); 
          break; 

         case Cell.CELL_TYPE_BLANK: 
          data.append("" + ","); 
          break; 
         default: 
          data.append(cell + ","); 

        } 
        data.append("\r\n"); 
       }} 
      } 

      fos.write(data.toString().getBytes()); 
      fos.close(); 

     } catch (Exception ioe) { 
      ioe.printStackTrace(); 
     } 
    } 
    //testing the application 

    public static void main(String[] args) { 
     //reading file from desktop 
     File inputFile = new File("D:\\files\\listing\\test.xlsx"); 
     //writing excel data to csv 
     File outputFile = new File("D:\\files\\listing\\test1.csv"); 
     xlsx(inputFile, outputFile); 

    } 
} 
+1

Устанавливает больше памяти в кучу Java. Google будет более чем рад помочь в этом. – ppeterka

+0

Каковы ваши аргументы VM? –

+0

Как это сделать в eclipse – user2696466

ответ

1

просто запустите приложение с

java -Xmx<whatever value in megs/gigs> yourApp 
+0

как это сделать в eclipse ??? – user2696466

+1

@ user2696466: настройте конфигурацию запуска/отладки проекта, которую вы используете. – haylem

+0

щелкните правой кнопкой мыши по свойствам проекта -> параметры запуска/отладки -> создайте конфигурацию для Java-приложения -> и установите их на вкладке параметров, например -> -Xmx1024M – OscarG

3

Увеличение кучи одно решение: java -Xmx<MegaBytes>M <YourClass>

Лучшим решением является использование меньшего объема памяти, который легко в вашем случае: почему вы храните весь результат в? 0 перед тем, как сбросить его в поток? Было бы гораздо более эффективно записывать каждую часть непосредственно в поток, как вы их находите.

Другое усовершенствование к вашему коду работать с FileWriter, а не FileOutputStream: он позволяет контролировать выходную кодировку, и принимает строки непосредственно, не требуя, чтобы позвонить String#getBytes().

2

Первый (хотя и не связанный с потреблением памяти), вы создаете текстовый файл, поэтому используйте FileWriter, а не FileOutputStream.

FileWriter writer = new FileWriter(outputFile); 

Во-вторых, вы строите очень длинную строку целиком в памяти. Очевидно, это потребляет много памяти. Лучше структурировать программу так, чтобы выходной файл генерировался при чтении входного файла без накопления всего в памяти. Например, заменить:

data.append(cell.getBooleanCellValue() + ","); 

с

writer.write(cell.getBooleanCellValue() + ","); 
0

я тоже сталкивался с таким же вопросом ОЫХ при разборе XLSX файла ... после двух дней борьбы, я, наконец, узнал, приведенный ниже код, который был действительно совершенен;

Этот код основан на sjxlsx. Он читает xlsx и хранится в листе HSSF.

  // read the xlsx file 
     SimpleXLSXWorkbook = new SimpleXLSXWorkbook(new File("C:/test.xlsx")); 

     HSSFWorkbook hsfWorkbook = new HSSFWorkbook(); 

     org.apache.poi.ss.usermodel.Sheet hsfSheet = hsfWorkbook.createSheet(); 

     Sheet sheetToRead = workbook.getSheet(0, false); 

     SheetRowReader reader = sheetToRead.newReader(); 
     Cell[] row; 
     int rowPos = 0; 
     while ((row = reader.readRow()) != null) { 
      org.apache.poi.ss.usermodel.Row hfsRow = hsfSheet.createRow(rowPos); 
      int cellPos = 0; 
      for (Cell cell : row) { 
       if(cell != null){ 
        org.apache.poi.ss.usermodel.Cell hfsCell = hfsRow.createCell(cellPos); 
        hfsCell.setCellType(org.apache.poi.ss.usermodel.Cell.CELL_TYPE_STRING); 
        hfsCell.setCellValue(cell.getValue()); 
       } 
       cellPos++; 
      } 
      rowPos++; 
     } 
     return hsfSheet; 
Смежные вопросы