问题描述
||
这个问题已经在这里有了答案:
解决方法
如前所述,您不应在程序逻辑中包括对OutOfMemoryErrors的处理。 OutOfMemoryError将被解释为“您的程序所需的内存比JVM / OS提供的更多”。
我建议您考虑返回
Iterator<ArrayList<Station>>
并根据需要延迟生成排列。 (您可能知道,返回的集合的大小很容易计算,而无需知道实际的内容。)
SwingWorker是正确的方法吗?
很可能没有。
,抓住OutOfMemoryError
,尽管您可能会遇到无法修理的情况。
请参阅以下讨论:http://www.velocityreviews.com/forums/t149419-catch-outofmemory-exception.html,以获取更多信息。
PS。您真的要获取数组中的所有排列吗?考虑aioobe的答案,就代码的可用性而言,这要好得多。
,如果内存不足,则没有足够的堆空间来绘制窗口和显示消息。因此,抓住它不会帮助您。至于显示有用的消息,建议您使用另一个进程来处理该进程的退出代码。
但是,为什么不避免出现内存不足错误呢?即使是小型机器也可以产生排列,您只需要牺牲运行时间即可。如何将中间结果保存到磁盘上?如果您不交付库(我想是因为您要显示错误消息,所以是这种情况),为什么不将内部模型更改为完全基于磁盘呢?
,您真的耗尽了内存吗?如果您要迭代处理列表,然后自己清理,可能是这样。但是,也许这只是不允许GC进行应做的工作的一种情况,java不能幸免于内存泄漏。悬挂引用,全局/静态变量等都可能导致对象在真正应该被GC处理时仍保留在作用域中。
运行探查器(其中很多可用于Eclipse)可能非常有用,以查看确切占用了如此大量内存的原因。
也许这将有助于小批量处理?过去处理财务数据后,我发现一次处理数百万条记录非常普遍。通常,处理这些情况的最佳方法是将处理分为较小的,更易于管理的块。
,您可以像捕获其他任何异常一样捕获OutOfMemoryError
,并根据需要进行报告。 SwingUtilities.invokeLater()
是在对话框中报告错误的好方法。并不是很容易恢复问题-从OutOfMemoryError回来通常是很轻松的(当然,如果现在有资格收集多余的对象)。
,我同意建议您逐步增加排列的答案。然后,总是可以在抛出OutOfMemoryError时恢复:
布尔型memoryFlag = false; //标志始终可用
尝试{
排列bigVar = ... //一些初始值
而(/ *条件* /){
//输出到目前为止发现的排列
bigVar = ... //计算下一个扩展的排列集
}
}
抓(OutOfMemoryError ex){
// bigVar现在超出范围,垃圾也是如此
System.gc();
memoryFlag = true;
}
//程序测试memoryFlag以报告是否发生内存不足
您的用户界面可以继续不间断地运行。以前在单线程应用程序中对我有用。对于多个线程,您将面临无法捕获错误的风险,因为每个线程都使用自己的处理程序运行,并且您可能无法控制某些Swing线程的范围。