在分配字节数组之前检查是否有足够的内存

时间:2015-04-09 08:58:27

标签: java

我需要将文件加载到内存中。在我这样做之前,我想确保我的VM中有足够的内存。如果不是,我想显示错误消息。我想避免OutOfMemory例外。

方法:

  1. 获取文件的文件大小
  2. 使用Runtime.getRuntime().freeMemory()
  3. 检查是否适合
  4. 这会有用还是你有其他建议吗?

3 个答案:

答案 0 :(得分:5)

任何“先检查然后再做”策略的问题是“检查”和“执行”之间可能会有变化,导致整个事情无用。

“尝试然后恢复”策略几乎总是一个更好的主意,不幸的是,这意味着尝试分配内存并处理异常。即使您执行“先检查”选项,您仍应编码分配可能失败的可能性。

一个典型的例子是在打开文件之前检查文件是否存在。如果有人要在你的检查和打开之间删除文件,那么无论最近文件是什么,你都会得到一个例外。

现在我不知道为什么你厌恶捕捉异常,但我恳请你重新考虑一下。由于Java很大程度上依赖于它们,如果你实际上没有控制你正在尝试的东西(例如打开文件或分配内存),它们通常被认为是一种很好的做事方式。


如果您从评论中看到,您担心内存会影响其他线程,那么如果您尝试为该文件分配一个大区域,情况就不应该如此。如果你只剩下400M并且你要求600,你的请求将会失败,但你仍然应该剩下400M。

只有当你的方式达到极限(比如尝试600次单独的1M分配)时,其他线程才会在你完成大约400次之后开始感受到压力。而这只会在你躲过的时候发生不要匆忙释放那400个。

所以也许有可能找出你需要多少空间,并确保你在一次点击中分配它。它既可以工作,也可以不工作。如果没有,你的其他线程就不会恶化。

我想你可以使用你建议的方法来尝试确保分配为其他线程留下一些空间(例如100M或10%或类似的东西),如果你是真的很担心。但我还是继续尝试。如果你的其他线程由于内存不足而无法完成工作,那么就有足够的先例告诉用户为VM提供更多内存。

答案 1 :(得分:1)

我个人建议不要将大量文件直接加载到内存中,而是尝试将其加载到块中或使用某种临时文件来存储中间数据。

答案 2 :(得分:1)

您可能需要查看FileChannel.map(FileChannel.MapMode, long, long)方法。这允许映射文件(想想POSIX mmap)而不填充堆。操作系统将(希望成功)为您处理内存。