Java中InputStream的内存问题
我需要将一个文件读入字节数组。整个文件需要读入数组。问题是,由于文件太大,我遇到了OutOfMemory错误。增加-XmX似乎没有任何效果。以下是代码片段: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 问题发生在字节数组实
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) {
}