我的磁盘中有40MB的文件,我需要使用字节数组将其“映射”到内存中。
最初,我认为将文件写入ByteArrayOutputStream是最好的方法,但我发现在复制操作期间的某个时刻它会占用约160MB的堆空间。
有人知道不使用三倍于RAM的文件大小的更好方法吗?
更新: 感谢您的回答。我注意到我可以减少内存消耗,告诉ByteArrayOutputStream初始大小比原始文件的大小稍大一点(使用与我的代码相同的大小强制重新分配,必须检查原因)。
还有一个高内存点:当我用ByteArrayOutputStream.toByteArray返回byte []时。看一下它的源代码,我可以看到它正在克隆数组:
public synchronized byte toByteArray()[] { return Arrays.copyOf(buf, count); }
我在想我可以扩展ByteArrayOutputStream并重写此方法,以便直接返回原始数组。鉴于流和字节数组不会被多次使用,这里是否存在潜在的危险?
MappedByteBuffer 可能就是您要寻找的。
MappedByteBuffer
不过,令我惊讶的是,要花费如此多的RAM来读取内存中的文件。您是否构建了ByteArrayOutputStream具有适当容量的?如果没有,则流可以在40 MB快要用完时分配一个新的字节数组,这意味着,例如,您将拥有39MB的完整缓冲区和两倍大小的新缓冲区。而如果流具有适当的容量,则不会有任何重新分配(更快),也不会浪费内存。
ByteArrayOutputStream