首页 > 移动平台 > 详细

2021-2-21:Java File MMAP 中,对 MappedByteBuffer 进行读写

时间:2021-02-21 23:52:03      阅读:41      评论:0      收藏:0      [点我收藏+]
我们来看底层实现:对于所有DirectByteBuffer的读写,都用到了Unsafe类的public native void putByte(Object o, long offset, byte x);方法,底层实现是:

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);   //设置值
  *(volatile native_type*)p = x;   t->set_doing_unsafe_access(false); UNSAFE_END \

那么这个获取地址的方法是啥样子呢?

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");
  //转换为int
  return (void*)(uintptr_t)addr;
}

这里我们看到,转换地址会被强制转换为int类型,所以只能映射 2GB - 1B 。

但是为何-XX:MaxDirectMemory可以指定比2G大的值呢?因为对于分配的直接内存中的 buffer,有对一个 BitMap 管理他们的基址,可以保证映射出对的地址,类似于堆内存的基址映射。但是对于文件映射内存,JVM 没有维护这么一个基址,或者说觉得没必要(一般不会有直接操作这么大文件的这么大内容的需求,大于2GB-1B我们多映射两次自己维护就行了)。

微信搜索“我的编程喵”关注公众号,每日一刷,轻松提升技术,斩获各种offer

技术分享图片

2021-2-21:Java File MMAP 中,对 MappedByteBuffer 进行读写

原文:https://blog.51cto.com/11418075/2633524

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!