Java中InputStream的内存问题

Java中InputStream的内存问题,java,inputstream,Java,Inputstream,我需要将一个文件读入字节数组。整个文件需要读入数组。问题是,由于文件太大,我遇到了OutOfMemory错误。增加-XmX似乎没有任何效果。以下是代码片段: InputStream in = new FileInputStream(file); long length = file.length(); byte[] out = new byte[(int)length]; // Process the byte array 问题发生在字节数组实

我需要将一个文件读入字节数组。整个文件需要读入数组。问题是,由于文件太大,我遇到了OutOfMemory错误。增加-XmX似乎没有任何效果。以下是代码片段:

InputStream in = new FileInputStream(file);
long length = file.length();                        
byte[] out = new byte[(int)length]; 
// Process the byte array

问题发生在字节数组实例化期间。是否有一种内存密集度较低的解决方法?

使用这种方法,您需要比最大的文件拥有更多的可用内存。考虑到一台24GB的机器成本不到2K英镑,这并不像过去那样愚蠢。实际上,字节[]的2GB限制在某些情况下更令人头痛

然而,通常读取InputStream的方法是一次读取8KB的块。这样,您只需要有远远超过8KB的空闲空间


顺便说一句:您可以使用-mx1g而不是您正在使用的选项。

否,如果您的文件太大而无法放入内存,则它太大而无法放入内存

更好的解决方案是尝试将流作为流进行处理,而不是将整个内容加载到内存中。如果不知道您试图实现什么样的处理,我们就无法真正判断这是否可行


例如,如果您只是试图计算文件的安全散列,您应该能够做到这一点,而无需一次加载大量数据-但如果您的处理需要随机访问数据,您可能需要使用
随机访问文件

工作区是,不要将整个文件加载到RAM中。事实上,您不能对大文件执行此操作,因为您必须一次性分配大量内存,这可能不起作用

问题是:您真的需要将整个文件存储在内存中吗

编辑

InputStream in = new FileInputStream(file);
long length = file.length();     
// At this point a warning should appear, because the code would
// not work for files larger than Integer.MAX_VALUE                   
byte[] out = new byte[(int)length]; 

使用内存映射文件如何:

发件人:


为什么需要将整个文件存储在内存中?50MB差不多,但对于现代系统来说并不太多。设置
-Xmx
应该会有所帮助,但是,您确定您使用它的方式正确吗,如
-Xmx256m
?由于问题发生在现有代码中,我想知道是否可以在不更改处理部件的情况下解决问题。看起来我必须一次读取文件的块。谢谢为什么Java不通过操作系统分配虚拟内存?@user1663987确实如此,但它有托管内存,并且托管内存的最大大小是有限的。所有其他区域、直接内存、元空间、线程堆栈和共享库都是通过操作系统创建的。
try {
    File file = new File("filename");

    // Create a read-only memory-mapped file
    FileChannel roChannel = 
      new RandomAccessFile(file, "r").getChannel();

    ByteBuffer readonlybuffer = 
      roChannel.map(FileChannel.MapMode.READ_ONLY, 
0, (int)roChannel.size());

    // Create a read-write memory-mapped file
    FileChannel rwChannel = 
      new RandomAccessFile(file, "rw").getChannel();

    ByteBuffer writeonlybuffer= 
      rwChannel.map(FileChannel.MapMode.READ_WRITE, 
  0, (int)rwChannel.size());

    // Create a private (copy-on-write) memory-mapped file.
    // Any write to this channel results in a private 
    // copy of the data.
    FileChannel pvChannel = 
      new RandomAccessFile(file, "rw").getChannel();

    ByteBuffer privatebuffer = 
      roChannel.map(FileChannel.MapMode.READ_WRITE, 
  0, (int)rwChannel.size());

} catch (IOException e) {
}