简体   繁体   English

为什么FileChannel.map会占用Integer.MAX_VALUE数据?

[英]Why does FileChannel.map take up to Integer.MAX_VALUE of data?

I am getting following exception when using FileChannel.map 我在使用FileChannel.map时遇到异常

Exception in thread "main" java.lang.IllegalArgumentException: Size exceeds Integer.MAX_VALUE
    at sun.nio.ch.FileChannelImpl.map(Unknown Source)
    at niotest.NioTest.readUsingNio(NioTest.java:38)
    at niotest.NioTest.main(NioTest.java:64)

Quickly looking into OpenJdk implementation shows that the method map(..) in FileChannelImpl takes size of type long as input. 快速查看OpenJdk实现显示FileChannelImpl中的方法map(..)将long类型的size作为输入。 But inside the body, it compares it with Integer.MAX_VALUE and throws error if its greater than that. 但是在体内,它将它与Integer.MAX_VALUE进行比较,如果它大于那,则抛出错误。 Why take long size as input but limit it to max integer length? 为什么将long尺寸作为输入但是将其限制为最大integer长度?

Anyone knows specific reason behind this implementation? 有谁知道这个实现背后的具体原因? or is it some kind of bug? 还是某种虫子?

Source URL - http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/nio/ch/FileChannelImpl.java 源URL - http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/nio/ch/FileChannelImpl.java

I am running this program using 64bit JRE on 64bit Windows-2k8 我在64位Windows-2k8上使用64位JRE运行此程序

It's not an implementation specific bug. 这不是特定于实现的错误。 The size is defined in the FileChannel.map as long, but... 大小在FileChannel.map中定义为long,但是......

size - The size of the region to be mapped; size - 要映射的区域的大小; must be non-negative and no greater than Integer.MAX_VALUE 必须是非负数且不大于Integer.MAX_VALUE

All compliant JVM implementations will be this way. 所有兼容的JVM实现都是这样的。 I suspect the reason is a combination of history (who would need to access a file larger than 2GB? ;) and trying to push things forward in later versions of Java (it will be easier to allow values larger than Integer.MAX than it will be to change the data type from int to long .) 我怀疑原因是历史的组合(谁需要访问大于2GB的文件?;)并试图在更高版本的Java中推进事情(允许大于Integer.MAX值比将更容易是将数据类型从int更改为long 。)

A lot of people find this int-based thinking in the Java API regarding anything File very confounding and short sighted. 很多人在Java API中发现这种基于int的思想有关任何文件非常混乱和短视。 But remember, Java start development in 1995! 但请记住,Java在1995年开始开发! I'm sure 2GB seemed like a relatively safe value at the time. 我敢肯定当时2GB似乎是一个相对安全的价值。

ByteBuffer's capacity is limited to Integer.MAX_VALUE, so there is no way to map anything larger than that. ByteBuffer的容量限制为Integer.MAX_VALUE,因此无法映射大于此值的任何内容。

Look at: MappedByteBuffer map(MapMode mode, long position, long size) 看看: MappedByteBuffer map(MapMode mode, long position, long size)
position has to be long for obvious reasons. 由于显而易见的原因, position必须很长。
size is not necessary to be long but in any calculation it has to be promoted - for example position+size has to be a positive long. size不需要很长,但在任何计算中都必须提升 - 例如,位置+尺寸必须是正长。 OS mapping indeed may use long to carry the mapping, map function (mmap) may need to map more than Integer.MAX_VALUE in order to preserve page size but ByteBuffer just can't use that. OS映射确实可能使用long来进行映射, map函数(mmap)可能需要映射多于Integer.MAX_VALUE才能保留页面大小但是ByteBuffer只是不能使用它。

Overall int lays very deep in java's design and there is no size_t C alike type, mass utilizing long instead of int will damper the performance. 整体int在java的设计中非常深入,并且没有size_t C类似的类型,使用long而不是int的质量将阻碍性能。 So in the end: if you need greater maps than 2GB, just use more than a single ByteBuffer. 所以最后:如果你需要比2GB更大的地图,只需要使用多个ByteBuffer。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM