简体   繁体   English

超出堆内存,java

[英]out of heap memory, java

i am new to java. 我是java的新手。 I am just trying to understand how to deal with heap memory overflow and its causes. 我只是想了解如何处理堆内存溢出及其原因。 Can somebody please help me in below code why it is throwing this error. 有人可以帮我下面的代码为什么它会抛出这个错误。 and how could i have avoided it. 我怎么能避免它。

error: 错误:

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) 线程“main”中的异常java.lang.OutOfMemoryError:java.lang上java.lang.Abstract数据库中的Java堆空间java.util.Arrays.copyOf(Arrays.java:2361)java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:117)。 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);

    }
}

Increasing heap is one solution: java -Xmx<MegaBytes>M <YourClass> 增加堆是一种解决方案: java -Xmx<MegaBytes>M <YourClass>

A better solution is to use less memory, which is easy in your case: why are you storing the whole output in a StringBuffer before dumping it in your stream? 更好的解决方案是使用更少的内存,这在您的情况下很容易:为什么要在将整个输出存储到流中之前将其存储在StringBuffer中? It would be much more memory efficient to write each part directly to the stream as you find them. 在找到它们时,将每个部分直接写入流将会更加节省内存。

Another improvement to your code is to work with a FileWriter rather than a FileOutputStream : it lets you control the output encoding, and accepts strings directly without requiring you to call String#getBytes() . 对代码的另一个改进是使用FileWriter而不是FileOutputStream :它允许您控制输出编码,并直接接受字符串,而无需调用String#getBytes()

First (though unrelated with memory consumption), you are creating a text file, so use a FileWriter rather than a FileOutputStream . 首先(虽然与内存消耗无关),您正在创建一个文本文件,因此请使用FileWriter而不是FileOutputStream

FileWriter writer = new FileWriter(outputFile);

Second, you are constructing a very long string entirely in memory. 其次,你在内存中构造一个非常长的字符串。 Obviously this consumes a lot of memory. 显然这会占用大量内存。 It's better to structure the program so that the output file is generated as you read the input file, without accumulating everything in memory. 最好构造程序,以便在读取输入文件时生成输出文件,而不会在内存中累积所有内容。 For example, replace: 例如,替换:

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

with

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

只需运行您的应用程序

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

I too faced the same issue of OOM while parsing xlsx file...after two days of struggle, I finally found out the below code that was really perfect; 在解析xlsx文件时我也遇到了同样的OOM问题......经过两天的挣扎,我终于发现下面的代码非常完美;

This code is based on sjxlsx. 此代码基于sjxlsx。 It reads the xlsx and stores in a HSSF sheet. 它读取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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM