The Unsafe class also uses the public native void putByte(Object O, long offset, byte X) for all DirectByteBuffer reads and writes. Method, the underlying implementation is:
The unsafe. CPP:
UNSAFE_ENTRY(void, Unsafe_SetNative##Type(JNIEnv *env, jobject unsafe, jlong addr, java_type x)) \ UnsafeWrapper("Unsafe_SetNative"#Type); \ JavaThread* t = JavaThread::current(); \ t->set_doing_unsafe_access(true); Void * p = addr_from_java(addr); \ // Set the value *(volatile native_type*)p = x; \ t->set_doing_unsafe_access(false); \ UNSAFE_END \Copy the code
So what does this method of getting the address look like?
The unsafe. CPP:
inline void* addr_from_java(jlong addr) { // This assert fails in a variety of ways on 32-bit systems. // It is impossible to predict whether native code that converts // pointers to longs will sign-extend or zero-extend the addresses. //assert(addr == (uintptr_t)addr, "must not be odd high bits"); Void *)(uintptr_t)addr; }Copy the code
Here we see that the cast address is cast to int, so only 2GB-1b can be mapped.
But why can -xx :MaxDirectMemory specify a value greater than 2G? Because buffers in allocated direct memory have a BitMap that manages their base address, it is guaranteed to map the correct address, similar to the base address map of heap memory. For file mapped memory, however, the JVM does not maintain such a base address, or does not feel the need to do so (there is generally no need to directly manipulate such large contents of such a large file, and more than 2GB-1B we can map twice and maintain ourselves).
Wechat search “my programming meow” public account, a daily brush, easy to improve skills, won a variety of offers