2014-10-26 184 views
1

我想加载内存(Files.readAllBytes)500Mb文件,我需要超过2 GB的堆大小。我想加载500Mb文件(Files.readAllBytes),我需要超过2 GB的堆大小。为什么?

使用默认设置我有OutOfMemoryError:Java堆空间。当我设置-Xmx1000m时它不起作用。它只有在设置至少-Xmx2300m -Xmx2300m时才有效。为什么Java需要这样的开销?

+1

尽管我无法回答具体的问题,但知道您正在尝试读取的文件类型(xml?)会很有用,因此可能会提出一种不同的方法。 – 2014-10-26 17:23:39

+0

当你这样做时,你会得到什么错误?你的程序是从字面上读取文件并存在,还是在读取文件之前做了一些其他工作? – dasblinkenlight 2014-10-26 17:25:34

+0

为什么不将它映射到内存中(使用'FileChannel.map()')? – fge 2014-10-26 17:28:07

回答

2

两个可能的答案浮现在脑海中,

  1. 库调用您使用的是复制缓冲区之间的字节一次以上,有效地倍增的内存,你所需要的量。
  2. 堆分为逻辑部分(世代)。当分配一个不适合一代的“大”对象时,该对象将被提前终结。如果旧有空间不足,则对象分配将失败。结合上面的1和一个小堆,可以看到Java如何打击麻烦。

这两个问题的最简单的解决方案是memory map the file代替,这将分配的内存断堆和非常有效/快于读取在该文件中,因为它降低参与OS上下文切换和字节缓冲器的份数阅读文件。

+0

我认为第一个变体是非常可能的,因为直接分配500Mb使用大约900Mb的堆大小。 – engineer 2014-10-26 18:46:58

相关问题