捕获OutOfMemoryError但没有堆大小增加[重复]

问题描述

||                                                                                                                   这个问题已经在这里有了答案:                                                      

解决方法

如前所述,您不应在程序逻辑中包括对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线程的范围。