java.lang.OutOfMemoryError:读取txt文件并写入xlsx文件时的java堆空间
我编程是为了创建一个工具,将编码的.txt文件翻译成可读的.xlsx文件。(我需要使用xlsx,因为我使用的列数超过256列,所以我在写行和列时使用XSSFWorkbook) 编码部分正常。。我知道这一点,因为我已经验证了好几次,但当我尝试在代码中添加新的编码映射时,所有结果都是:java.lang.OutOfMemoryError:读取txt文件并写入xlsx文件时的java堆空间,java,memory,Java,Memory,我编程是为了创建一个工具,将编码的.txt文件翻译成可读的.xlsx文件。(我需要使用xlsx,因为我使用的列数超过256列,所以我在写行和列时使用XSSFWorkbook) 编码部分正常。。我知道这一点,因为我已经验证了好几次,但当我尝试在代码中添加新的编码映射时,所有结果都是: Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Unknow
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.io.ByteArrayOutputStream.write(Unknown Source)
at org.apache.poi.openxml4j.opc.internal.MemoryPackagePartOutputStream.write(MemoryPackagePart OutputStream.java:88)
at org.apache.xmlbeans.impl.store.Cursor._save(Cursor.java:590)
at org.apache.xmlbeans.impl.store.Cursor.save(Cursor.java:2544)
at org.apache.xmlbeans.impl.values.XmlObjectBase.save(XmlObjectBase.java:212)
at org.apache.poi.xssf.usermodel.XSSFSheet.write(XSSFSheet.java:2480)
at org.apache.poi.xssf.usermodel.XSSFSheet.commit(XSSFSheet.java:2439)
at org.apache.poi.POIXMLDocumentPart.onSave(POIXMLDocumentPart.java:196)
at org.apache.poi.POIXMLDocumentPart.onSave(POIXMLDocumentPart.java:200)
at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:204)
at model.Conversione.traduzioneFile(Conversione.java:241)
at model.Main.scriviFile(Main.java:76)
at model.Main.main(Main.java:52)
错误发生在3000/4000行之后,内存是这样运行的
起始值:
14443720
**:13572128
**:12078128
**:10575592
**:14126224->新增加值始终低于起始值,然后降低
**:12559920
**:11811440
**:10229128
**:13751400->。。。
**:13011080
“编码映射”通常是HashMap
类型的映射。
(我这样做是因为我不能使用数据库.)
所以程序主要是:
-首先实例化并创建整个地图,
-从.txt文件中读取行,
-拆分行,获取一个标记,使用地图将其转换为行和列
-wb.write(文件输出流)
-结束
即使在翻译操作中没有考虑到我添加的地图,我也无法理解为什么会发生此错误
为什么内存量如此多变?(但永远不要回到起始值?)
如果我在某些方面不清楚,请询问。。我不知道该怎么办
起初,我认为这是一个.xlsx文件越来越大的缓冲问题(即使..如我所说..没有任何变化,因为没有使用新的映射)
如有任何提示,我们将不胜感激
Lucia您可以使用jvisualvm或jmap-histo:live检查占用内存的内容。如果应用程序确实需要内存,您可以尝试增加内存限制-Xmx…默认情况下,Eclipse将分配多达384 MB的Java堆内存。对于所有典型的开发任务来说,这应该足够了。但是,根据您正在运行的JRE、您正在使用的其他插件的数量以及您将使用的文件的数量,您可能需要增加这个数量。Eclipse允许您使用-vmargs命令行参数直接将参数传递给Java VM,该参数必须在所有其他Eclipse特定参数之后。因此,为了增加可用堆内存,您通常会使用:
eclipse -vmargs -Xmx<memory size>
eclipse-vmargs-Xmx
将该值设置为大于“384M”(384MB——默认值)
使用Oracle(Sun)VM时,可能还需要增加永久性生成内存的大小。默认最大值为64 MB,但根据插件配置和使用情况,可能需要更多。当VM耗尽永久生成内存时,它可能会在类加载期间崩溃或挂起。使用Sun JRE版本1.5.0_07或更高版本时,此故障不太常见。使用-XX:MaxPermSize=参数增加最大永久生成大小:
**eclipse -vmargs -XX:MaxPermSize=<memory size>**
**eclipse-vmargs-XX:MaxPermSize=**
这与缓冲无关。内存不足是因为堆中的对象太多和/或最大内存的-Xmx
设置太低。您可以在Eclipse中与测试/实用程序对应的参数选项卡中的“运行配置”中增加-Xmx
。在VM参数块中添加-Xmx 512M
(大约)
但真正的问题是,您试图同时在内存中存储太多的对象。我不确定我是否理解你的
HashMap
的HashMap
。如果文本文件中每行都有一个HashMap
,那么这将占用大量内存@AKJ的回答提供了一些工具来诊断哪些物体占用了最多的空间。是一个很好的起点。如果您在运行独立java应用程序时在eclipse中遇到这个问题。右键单击java程序,然后单击“运行方式->运行配置”。单击参数选项卡,并在VM参数字段中键入-Xms1024M-Xmx1024M。这会在从eclispe运行时增加VM大小。我建议您使用SXSSFWorkbook(需要Apache POI>=3.8 beta 3)而不是建议使用的XSSFWorkbook
创建一个行访问窗口大小为20的工作簿,即内存中最多只保留20行,其余的刷新到磁盘上
执行此操作时需要注意一些陷阱,如果需要调用SXSSFSheet.autoSizeColumn(int),请避免将空值放入单元格中,并尽快调用SXSSFSheet.TrackAllColumnsFrautosizing()(需要Apache POI>=3.15)稍后,我将自动计算列的大小。我想我无法增加内存,因为我仍然需要添加大量映射,所以我会得出相同的结论。。现在我正试图理解如何使用jvisualvm。多谢了,这与eclipse的记忆无关。这与eclipse在运行其测试和程序时添加的VM设置有关。您可以从运行配置菜单和参数选项卡中获得。
final SXSSFWorkbook workbook = new SXSSFWorkbook(20);