【问题标题】:out of heap memory, java堆内存不足,java
【发布时间】:2013-09-10 17:12:47
【问题描述】:

我是 Java 新手。我只是想了解如何处理堆内存溢出及其原因。有人可以在下面的代码中帮助我为什么它会抛出这个错误。我怎么能避免它。

错误:

线程“主”java.lang.OutOfMemoryError 中的异常:Java 堆空间 在 java.util.Arrays.copyOf(Arrays.java:2361) 在 java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:117) 在 java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:406) 在 java.lang.StringBuffer.append(StringBuffer.java:237) 在 com.ugam.qa.tittle.XlsxToCsv.xlsx(XlsxToCsv.java:49) 在 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);

    }
}

【问题讨论】:

  • 为 Java 堆设置更多内存。 Google 非常乐意在这方面提供帮助。
  • 你的虚拟机参数是什么?
  • 如何在eclipse中做到这一点
  • 谷歌:java 堆日食。不要偷懒。我们不会解决您的所有问题。

标签: java out-of-memory heap-memory


【解决方案1】:

只需使用

运行您的应用程序
java -Xmx<whatever value in megs/gigs> yourApp

【讨论】:

  • @user2696466:配置你使用的项目的运行/调试配置。
  • 右键单击项目属性 -> 运行/调试设置 -> 为 Java 应用程序创建配置 -> 并在参数选项卡上设置这些 -> -Xmx1024M
【解决方案2】:

增加堆是一种解决方案:java -Xmx&lt;MegaBytes&gt;M &lt;YourClass&gt;

更好的解决方案是使用更少的内存,这在您的情况下很容易:为什么在将整个输出转储到流中之前将其存储在 StringBuffer 中?在找到它们时将每个部分直接写入流中会更节省内存。

对代码的另一项改进是使用FileWriter 而不是FileOutputStream:它允许您控制输出编码,并直接接受字符串,而无需您调用String#getBytes()

【讨论】:

    【解决方案3】:

    首先(尽管与内存消耗无关),您正在创建一个文本文件,因此请使用FileWriter 而不是FileOutputStream

    FileWriter writer = new FileWriter(outputFile);
    

    其次,您正在构建一个完全在内存中的非常长的字符串。显然这会消耗大量内存。最好对程序进行结构化,以便在您读取输入文件时生成输出文件,而无需在内存中累积所有内容。例如,替换:

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

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

    【讨论】:

      【解决方案4】:

      我在解析xlsx文件时也遇到了同样的OOM问题……经过两天的努力,我终于发现下面的代码真的很完美;

      此代码基于 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;
      

      【讨论】:

        猜你喜欢
        • 2014-08-02
        • 1970-01-01
        • 2021-11-20
        • 1970-01-01
        • 1970-01-01
        • 2014-05-18
        • 1970-01-01
        • 2020-01-23
        • 2014-01-04
        相关资源
        最近更新 更多