java.lang.OutOfMemoryError:比较两个excel文件时超出了GC开销限制

java.lang.OutOfMemoryError:比较两个excel文件时超出了GC开销限制,java,garbage-collection,out-of-memory,Java,Garbage Collection,Out Of Memory,我得到java.lang.OutOfMemoryError:GC开销限制超过了异常,同时比较了两个类似这样的excel工作表 public void compareExcels(String primaryKey, String path1, String path2, String OutPath) throws Exception{ ArrayList<ArrayList<String>> dataSheet1 = new ArrayList<Ar

我得到java.lang.OutOfMemoryError:GC开销限制超过了异常,同时比较了两个类似这样的excel工作表

   public void compareExcels(String primaryKey, String path1, String path2, String OutPath) throws Exception{
    ArrayList<ArrayList<String>> dataSheet1 = new ArrayList<ArrayList<String>>();
    ArrayList<ArrayList<String>> dataSheet2 = new ArrayList<ArrayList<String>>();
    ExcelUtilities obj = new ExcelUtilities();      
    /*Read both the worksheets in ArrayList<ArrayList<String>> objects */
    /*Apache POI api is used for reading excel data*/
    dataSheet1 = obj.readExcel(path1);
    dataSheet2 = obj.readExcel(path2);
    /* pk holds the key column name using which comparison should be done*/
    ArrayList<String> pk = new ArrayList<String>(Arrays.asList(primaryKey.split(";")));
    /* compare method takes care of comparing the two ArrayList<ArrayList<String>> objects and returns a map with row number and match result */
    HashMap<Integer, String> result = obj.compare(dataSheet1,dataSheet2,pk);    
    /* Mismatch excel report is created*/
    obj.writeToExcel(result, OutPath+"result.xlsx");
 }
public void compareExcels(字符串primaryKey、字符串路径1、字符串路径2、字符串输出路径)引发异常{
ArrayList数据表1=新的ArrayList();
ArrayList数据表2=新的ArrayList();
ExcelUtilities obj=新的ExcelUtilities();
/*阅读ArrayList对象中的两个工作表*/
/*ApachePOIAPI用于读取excel数据*/
dataSheet1=obj.readExcel(路径1);
dataSheet2=obj.readExcel(路径2);
/*pk保存键列名,应使用该列名进行比较*/
ArrayList pk=newArrayList(Arrays.asList(primaryKey.split(“;”));
/*compare方法负责比较两个ArrayList对象,并返回一个带有行号和匹配结果的映射*/
HashMap结果=对象比较(数据表1、数据表2、pk);
/*创建了不匹配的excel报告*/
obj.writeToExcel(结果,输出路径+“result.xlsx”);
}
上面的代码在处理几千条excel记录时工作得非常好。但当输入表的大小增加到每个excel表中的50k条记录时,程序运行到java.lang.OutOfMemoryError:GC开销超出了限制

我明白-

  • java虚拟机无法分配对象时,会抛出java.lang.OutOfMemoryError,因为该对象内存不足,垃圾收集器无法提供更多内存
  • 我试图将大量数据读入两个
    ArrayList
    对象,这可能是导致此问题的根本原因
  • 要解决这个问题,一个选项是增加堆大小,提到我想要扩展的堆大小
    • Xmx-最大堆大小

  • 但这不是一个优雅的解决方案。我可能需要这个程序来比较两张excel表格,每张表格有一百万条记录。我想用正确的数据结构实现一个高效的算法。需要你的思考。

    你写的是
    ExcelUtilities
    类吗?我在POI文档中没有看到它。一般来说,您似乎正在尝试将整个Excel文档读入内存,而减少这种情况的唯一方法是找出如何在内存中读取文件的块,并同时比较块而不是整个文件。确切的解决方案将取决于Excel文件是什么,以确定如何将其分块。是的
    ExcelUtilities
    是我编写的类,它有读取、写入excel的方法。ApachePOI用于实现这些方法。不幸的是,我认为没有人能够回答这个问题,因为它对于您所编写的代码来说太具体了,太宽泛了,无法缩小到您可以实现的特定更改。如上所述,如果你想解决这个问题,你必须制定一个策略,在操作时不要将整个文件加载到内存中。