我正在尝试使用apache POI 3.10将Excel文件(xlsx)加载到工作簿对象中。

我收到一个java.lang.OutofMemoryError。

我在JVM上使用带有-Xmx2g参数的Java 8。

当我运行程序时,所有4个内核(64位系统)和我的RAM(4gb)都已用完。

Excel工作表具有43列和166,961行,等于7,179,323个像元。

我正在使用Apache POIs WorkBookFactory.create(new File),因为它比使用InputFileStream占用更少的内存。

是否有人对如何优化内存使用或创建工作簿的其他方式有任何想法?

下面是我的测试Reader类,不要判断,它很粗糙,并且包含调试语句:

import java.io.File;
import java.io.IOException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

public class Reader {

    private Workbook wb;

    public Reader(File excel) {
        System.out.println("CONSTRUCTOR");
        wb = null;
        try  {
            wb = WorkbookFactory.create(excel);
        } catch (IOException e) {
            System.out.println("IO Exception");
            System.out.println(e.getMessage());
        } catch (InvalidFormatException e) {
            System.out.println("Invalid Format");
            System.out.println(e.getMessage());
        }
    }

    public boolean exists() { return (wb != null); }

    public void print() {}

    public static void main(String[] args) {
        System.out.println("START PRG");
        //File f = new File("oldfilename.xls");
        File f = new File("filename.xlsx");
        System.out.println("PATH:" + f.getAbsoluteFile());
        if (!f.exists()) {
            System.out.println("File does not exist.");
            System.exit(0);
        }
        System.out.println("FILE");
        Reader r = new Reader(f);
        System.out.println("Reader");
        r.print();
        System.out.println("PRG DONE");
    }
}

最佳答案

显然,加载24mb文件不应该引起OOM ...

乍一看,虽然Xmx设置为2G,但实际上系统中没有多少可用内存。换句话说,操作系统和其他进程可能已经占用了4G物理内存中的2G以上!首先检查可用的物理内存。如果可用情况低于预期,请尝试关闭其他一些正在运行的应用程序/进程。

如果不是这种情况,并且确实有足够的内存,那么不进行概要分析就很难确定真正的原因。使用配置文件工具检查与内存相关的JVM状态。您可以简单地使用jconsole(JDK随附)。 @请参见this on how to activate JMX

连接后,检查与内存相关的读数,尤其是在内存空间下方:


老一代
年轻一代
烫发


监视这些空间,看看它在哪里挣扎。我认为这是一个独立的应用程序。如果将其部署在服务器(作为Web或服务)上,则可以考虑使用“ -XX:NewRatio”选项来有效地分配堆空间。 @see调整相关详细信息here

10-08 00:23