我正在编写一个应用程序,使用apache-POI生成一个大的xlsx文件。 在某个时间我得到了OutOfHeapSpace异常。
我想通过将内容写入xlsx文件来解决它,当我确定我很快就会没有空间,从而释放内存,然后从磁盘读取文件并继续写入。
更好的解决方案可能是预定义我将在每个“块”中写入的单元格数,然后将块写入磁盘,但无论如何这让我想知道是否有办法确定堆空间那是在运行时留下的?
答案 0 :(得分:3)
MemoryMXBean可以为您提供有关当前内存使用情况的大量信息。
public class PrintMemory {
public static void main(String[] args) {
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
long[] array;
for (int i = 0; i < 100; i++) {
array = new long[100000];
System.out.printf("%d%n", memoryMXBean.getHeapMemoryUsage());
}
}
}
答案 1 :(得分:3)
在运行时释放未使用的内存可能不是很可靠,因为JVM在决定何时进行垃圾收集时有相当大的自由度。
POI最近introduced the SXSSF API使用流媒体,从而显着减少了编写电子表格的内存占用空间。这应该有助于甚至非常大的xsls文件。显示了一些缺点here。但是如果你能和他们一起生活,这可以减轻堆相关的问题。
答案 2 :(得分:2)
您可以获得可用内存,但它只会告诉您在不触发GC的情况下分配的最多内存。
相反,您可以触发GC并查看病房后有多少内存空闲。这个问题是它有执行开销。
另一种选择是通过JMX监控GC清理并查看自然触发GC后有多少空闲(如果它没有运行,你没有问题)
答案 3 :(得分:1)
使用JVM JMX MBeans中的一个是值得考虑的。 像这个MemoryPoolMXBean