8288分类目录 8288分类目录 8288分类目录
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

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

来源:本站原创 浏览:49次 时间:2023-01-13

我们来看底层实现:对于所有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:

  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net