2011-12-18 69 views
3

我有一个程序为目录(子)树中的每个文件创建一个对象。在大型和大型磁盘的这些日子里,没有办法知道将会有多少文件,尤其是,而不是几年(几个月)。检测OutOfMemory的异常情况

我的程序不是企业关键的;它是用户分析该子树的工具。因此,告诉用户在该环境中没有足够的内存来操作该子树是可以接受的。他可以通过选择该子树的子树来做他想做的事情。

但是程序不能接受只死或堆栈跟踪或其他只有程序员可以爱的东西。我希望该计划能够向用户提供一些合理的反馈意见,并让他控制他所做的工作。

我已经阅读了StackOverflow关于OOM异常的一些帖子,并且在主要内容中我同意了许多观点:设计不当的应用程序,内存泄漏等等,都是需要考虑的问题。 。但在这种情况下,我可能有人试图在10T磁盘上使用我的工具,该磁盘只有比准备分析的程序更多的文件。而且我并没有试图编写这个工具,因此它可以在任何可能的子树上运行。

我曾经看到有人认为OOM可以像“其他异常”一样被捕获;不幸的是,这不是一个强有力的做事方式。当OOM被抛出时,一些线程可能已经死亡,我们无法确定它会是哪一个线程,我们无法重新启动它。因此,例如,如果它碰巧是Swing的关键之一,那么我们运气不好。

所以我现在的想法是,我的程序需要偶尔看起来(至少)的可用内存的可用量,并停止自己,如果低于某个阈值。我可以测试一些事情来确定一个阈值,允许我输出一个带有消息的对话框,然后将所有对我的对象的引用擦除。

但是,如果我错过了某些东西,或者有更好的方法去解决问题,我想知道它。

+1

我会亲自使用像lucene这样的东西,并将文件系统索引到磁盘。我没有理由认为它应该在记忆中。另外,如果你确实需要一个庞大的内存索引,那就是你需要的,你需要相应地分配堆 – aishwarya 2011-12-18 04:17:53

+0

@aishwarya:在阅读问题时我想到了同样的事情。 +1 – DaveFar 2011-12-18 08:35:36

+1

检查可用内存的问题是它只显示已知的可用内存,而不会在GC运行时释放多少内存。这意味着,只要GC运行时有大量内存可用,您可能会停止在低内存上进行处理。这可以接受吗? – 2011-12-18 10:21:30

回答

1

看到我的帖子here。为什么在你填充树时不计算freeMemory,并停在某些(可能是用户可配置的)点上,例如:占用了90%的堆。您应该尽量保持为每个文件创建的对象尽可能小。你可以粘贴这个数据结构的代码,这样我们可以批评它,看看它是否可以做得更小?也许你不需要直接拥有一个对象,而是一个可以根据请求获取相关信息的代理对象。

+0

@DaveBall - 干杯。 – 2011-12-18 08:45:40

1

这里有没有直接回答,只是我的2什么办法我反而采取美分:

这样一个程序(或API)的用户,我很高兴能得到反馈/估计/尽早,例如控制:

  • 得到一个警告,如“有42个fantastillion许多文件在指定目录下,这将需要大约5个小时的处理和2GB内存”
  • 是能够设置最大数量的文件(也许用过滤器来获得最相关的文件),或者遍历子树的最大递归深度
  • 让程序通过目录结构进行广度优先搜索(而不是深度优先搜索),并且在太大的目录允许用户选择中止分析,或者忽略当前目录,或者忽略当前子树。

我也能接受等待一段时间的预处理,如果我得到了适当的反馈,如“预处理:遍历子目录估算所需的时间和记忆”,并估算好之后。

通过合理的估计,我认为您不需要复杂的内存使用情况监视。如果OOM异常仍然很少出现,我宁愿遵循aishwarya的方法并写入磁盘,而不是将所有信息保存在内存中。