当前位置: 首页 > news >正文

seo网站快速排名网站免费打包

seo网站快速排名,网站免费打包,连云港网站建设价格,哪些网站自己做宣传文章目录 1. 前言2. MappedByteBuffer3. 例子4. 属性5. 构造器6. mappingOffset、mappingAddress、mappingLength7. isLoaded 判断内存是否还在内存中8. load 方法将 ByteBuffer 加载到 Page Cache 中9. force 刷盘 1. 前言 上一篇文章我们介绍了 HeapByteBuffer 的源码#… 文章目录 1. 前言2. MappedByteBuffer3. 例子4. 属性5. 构造器6. mappingOffset、mappingAddress、mappingLength7. isLoaded 判断内存是否还在内存中8. load 方法将 ByteBuffer 加载到 Page Cache 中9. force 刷盘 1. 前言 上一篇文章我们介绍了 HeapByteBuffer 的源码这篇文章我们来介绍下 MappedByteBuffer这个 MappedByteBuffer 是 DirectByteBuffer 的父类。 【源码解析】Java NIO 包中的 Buffer【源码解析】Java NIO 包中的 ByteBuffer【源码解析】Java NIO 包中的 HeapByteBuffer 2. MappedByteBuffer MappedByteBuffer 是 ByteBuffer 的子类表示一个直接字节缓冲区其内容是文件的内存映射区域。通过 MappedByteBuffer程序可以直接对文件内容进行读写操作而无需通过传统的 I/O 流或通道。 相比传统的文件 IO 操作比如 FileInputStream 和 FileOutputStream这种方式可以直接对内存中的数据进行操作操作系统会负责将内存中的更改同步到磁盘文件中。 MappedByteBuffer 通过 FileChannel 的 map 方法创建创建的时候可以设置三种模式 MapMode.READ_ONLY只读模式映射的缓冲区是只读的MapMode.READ_WRITE读写模式映射的缓冲区是可读写的对缓冲区的修改会同步到文件中MapMode.PRIVATE私有模式映射的缓冲区是可写的但修改不会同步到文件中而是创建一个私有副本 但是由于 MappedByteBuffer 使用的是堆外内存所以如果尝试映射过大的文件可能会导致内存不足OutOfMemoryError毕竟内存映射文件的大小受操作系统和可用物理内存的限制。 所以最后总结一下当需要频繁读写大文件或者需要随机文件访问的时候就可以使用这个 MappedByteBuffer。 3. 例子 首先我们需要生成一个 1G 的文件。 public class FileTest {public static void main(String[] args) {String filePath D:\\学习资料\\计算机编程语言java学习\\后台\\JDK源码\\jdk1.8Source\\src\\test\\file\\hello.txt; // 生成的文件路径long fileSizeInBytes 1024L * 1024 * 1024; // 1GBtry {generateFile(filePath, fileSizeInBytes);System.out.println(文件生成成功路径: filePath);} catch (IOException e) {System.err.println(文件生成失败: e.getMessage());}}/*** 生成指定大小的文件内容为 helloWorld 的重复填充** param filePath 文件路径* param fileSizeInBytes 文件大小字节* throws IOException 如果写入失败*/public static void generateFile(String filePath, long fileSizeInBytes) throws IOException {// helloWorld 的字节数byte[] content helloWorld.getBytes();int contentLength content.length;try (FileOutputStream fos new FileOutputStream(filePath);BufferedOutputStream bos new BufferedOutputStream(fos)) {// 写入次数long len fileSizeInBytes / contentLength;// 一次写入 helloWorld 字节数for (long i 0; i len; i) {bos.write(content);}// 剩余字节long remainingBytes fileSizeInBytes % contentLength;if (remainingBytes 0) {bos.write(content, 0, (int) remainingBytes);}}} } 生成了 hello.txt 之后可以看下面图。 生成 1G 的文件之后我们再来看下传统的 IO 读取数据和 MappedByteBuffer 读取数据的效率。 public class MappedByteBufferPerformance {public static void main(String[] args) throws Exception {String filePath D:\\学习资料\\计算机编程语言java学习\\后台\\JDK源码\\jdk1.8Source\\src\\test\\file\\hello.txt; // 生成的文件路径long fileSize 1024 * 1024 * 1024; // 1GBlong startTime System.currentTimeMillis();try (RandomAccessFile file new RandomAccessFile(filePath, r);FileChannel channel file.getChannel()) {MappedByteBuffer buffer channel.map(FileChannel.MapMode.READ_ONLY, 0, fileSize);// 读取文件内容while (buffer.hasRemaining()) {buffer.get(); // 读取一个字节}}long endTime System.currentTimeMillis();System.out.println(MappedByteBuffer 读取时间: (endTime - startTime) ms);} }首先上面是 MappedByteBuffer 的读取总共用了 317 ms如下图所示。 下面我们再来看下使用传统 IO 来读取文件的耗时。 public class BufferedIOPerformance {public static void main(String[] args) throws Exception {String filePath D:\\学习资料\\计算机编程语言java学习\\后台\\JDK源码\\jdk1.8Source\\src\\test\\file\\hello.txt; // 生成的文件路径long startTime System.currentTimeMillis();try (FileInputStream fis new FileInputStream(filePath);BufferedInputStream bis new BufferedInputStream(fis)) {// 读取文件内容while (bis.read() ! -1) {// 读取一个字节}}long endTime System.currentTimeMillis();System.out.println(普通 I/O 读取时间: (endTime - startTime) ms);} }普通 IO 的读取耗时如下 所以这里总结下读取的结果 操作方式文件大小读取时间备注MappedByteBuffer1 GB317 ms直接内存映射效率极高BufferedInputStream1 GB19552 ms带缓冲区的普通 I/O速度较慢 4. 属性 MappedByteBuffer 中只有一个属性 fd其他属性都在父类 ByteBuffer 中。 private final FileDescriptor fd; 是 Java 中用于表示操作系统文件描述符的对象。它允许 Java 程序与底层的文件系统进行交互。说白了这玩意就是用来映射文件到内存的。 5. 构造器 MappedByteBuffer(int mark, int pos, int lim, int cap, // package-privateFileDescriptor fd) {super(mark, pos, lim, cap);this.fd fd; }MappedByteBuffer(int mark, int pos, int lim, int cap) {super(mark, pos, lim, cap);this.fd null; }这两个构造器其实就是一个指定了文件描述符一个没有指定。 6. mappingOffset、mappingAddress、mappingLength private long mappingOffset() {// 页大小int ps Bits.pageSize();// 求直接内存的偏移量long offset address % ps;// 确保一定是正数return (offset 0) ? offset : (ps offset); }private long mappingAddress(long mappingOffset) {// address 表示缓冲区的起始地址// mappingOffset 是上面的偏移量return address - mappingOffset; }private long mappingLength(long mappingOffset) {return (long)capacity() mappingOffset; }第一个方法 mappingOffset 获取的是 MappedByteBuffer 的内存地址相对于内存页面起始位置的偏移量 Bits.pageSize(): 这里面返回的是操作系统的内存分页大小一般是 4KB 或者 8KB这里取决于用什么操作系统。在进行内存映射的时候可以用这个方法求出偏移量来进行内存对齐。 第二个方法 mappingAddress 用来计算内存页面的起始地址这里的 mappingOffset 一般就是上面的 mappingOffset 方法。address - mappingOffset 这个方法就是使用缓冲区 ByteBuffer 的起始地址减去偏移量。 第三个方法 mappingLength 求出的是内存映射文件的总长度也就是 mmap 文件映射的内容区域。 上面这几个方法就是获取 MappedByteBuffer 的各种地址信息那为什么又要有一个偏移量呢我们知道操作系统分配最小单位是一个页所以当使用 mmap 映射操作系统内存的时候分配的内存总是一个页的起始位置。 虽然我们获取了 MappedByteBuffer但是这个 MappedByteBuffer 的起始位置有可能不是一个页的起始位置也就是说上面图中 mappingAddress 是页的起始位置但是 MappedByteBuffer 里面的起始地址是 address。操作系统分配内存肯定是一个页来分配的所以 MappedByteBuffer 的起始地址和实际分配的有可能不一样相差就是 mappingOffset。上面的 mappingOffset 求出来的就是 mappingAddress - address 之间的距离而 mappingAddress 求出来的就是操作系统内核实际调用 mmap 分配的内存页起点就是上图的 mappingAddress最后一个方法 mappingLength 求出来的就是 mmap 实际分配的内存容量。 7. isLoaded 判断内存是否还在内存中 public final boolean isLoaded() {// 判断 MappedByteBuffer 有没有映射到一个文件checkMapped();// 如果起始地址为 0 或者容量为 0if ((address 0) || (capacity() 0))// 表示已经不在物理内存里面了return true;// 获取 mmap 分配的内存的起始位置也就是图中的 mappingOffsetlong offset mappingOffset();// MappedBuffer 实际映射的内存区域大小 也是 mmap 实际分配的内存大小long length mappingLength(offset);// mappingAddress(offset) 获取实际的映射起始位置 mapPosition// Bits.pageCount(length) 表示分配了多少个页// 调用 native 方法return isLoaded0(mappingAddress(offset), length, Bits.pageCount(length)); }private native boolean isLoaded0(long address, long length, int pageCount);如果结果是 true表示缓冲区的内容很可能已经驻留在物理内存中访问这些数据时不会触发虚拟内存页错误或 I/O 操作。如果返回 false并不一定表示缓冲区的内容没有驻留在物理内存中可能只是部分数据不在物理内存中。 8. load 方法将 ByteBuffer 加载到 Page Cache 中 public final MappedByteBuffer load() {// 判断文件描述符是不是空checkMapped();if ((address 0) || (capacity() 0))return this;// 获取 mmap 内存地址到 MappedByteBuffer 的距离long offset mappingOffset();// 获取 mmap 分配的内存长度long length mappingLength(offset);// 调用 native 将 MappedByteBuffer 中的内容预读到 page cache 中load0(mappingAddress(offset), length);// Read a byte from each page to bring it into memory. A checksum// is computed as we go along to prevent the compiler from otherwise// considering the loop as dead code.Unsafe unsafe Unsafe.getUnsafe();// 一个页的大小int ps Bits.pageSize();// 这个 ByteBuffer 分配了多少个页int count Bits.pageCount(length);// 获取 mmap 映射地址的起始地址long a mappingAddress(offset);byte x 0;// 从 mmap 起始地址开始遍历所有页每遍历一次访问一下都会发生缺页中断// 同时将 MappedByteBuffer 和 Page Cache 进行页表映射for (int i0; icount; i) {x ^ unsafe.getByte(a);a ps;}if (unused ! 0)unused x;return this; }这个方法会将 ByteBuffer 内容里面的数据加载到 Page Cache 中并且这个方法还会遍历所有页预读一次。因为数据加载到 Page Cache 之后并不会立刻就生成虚拟内存到物理内存的映射。所以加载到 Page Cache 的物理页之后需要访问一次发生缺页中断这时候才会生成页表项。 9. force 刷盘 public final MappedByteBuffer force() {checkMapped();if ((address ! 0) (capacity() ! 0)) {// 核心逻辑从 mmap 映射的起始位置开始将映射的内容进行刷盘long offset mappingOffset();force0(fd, mappingAddress(offset), mappingLength(offset));}return this; }private native void force0(FileDescriptor fd, long address, long length);这个方法就是将 Buffer 里面的数据进行刷盘。 如有错误欢迎指出
http://www.w-s-a.com/news/783464/

相关文章:

  • 彩票网站建设seo优化师是什么
  • 怎么做英文网站网站建设基本费用
  • dede网站名称不能保存wordpress运费设置
  • 出口网站制作好一点的网站建设
  • 在小说网站做编辑怎么找韶关市建设局网站
  • 网站策划怎么做内容旅游型网站建设
  • 东莞百度网站推广ppt模板免费下载的网站
  • 网站建设项目管理基本要求网站空间到期影响
  • 做奖杯的企业网站谁有推荐的网址
  • wordpress能做企业站吗wordpress收发邮件
  • 电子产品网站建设策划方案腾讯企业邮箱注册申请免费
  • 哪些网站可以免费做代码自己电脑做网站服务器广域网访问
  • 高端网站设计青海省教育厅门户网站学籍查询
  • 长春网站优化公司网站制作400哪家好
  • 县级门户网站建设的报告开发游戏的软件有哪些
  • 做电子商务的网站wordpress带会员中心
  • 网站域名不变网站可以从做吗网站建设步骤 文档
  • 网站建设中 gif互联网新项目在哪里找
  • 做外包网站猎头公司英文
  • 房屋结构自建设计 网站海淀教育互动平台
  • 网络营销比赛 营销型网站策划热门搜索关键词
  • 网站建设图片代码网络设计师工资
  • 福建网站开发适合交换友情链接的是
  • 企业门户网站建站内乡微网站开发
  • 在线做logo印章网站一般到哪个网站找数据库
  • 哪些网站做免费送东西的广告6郑州人流医院哪家好
  • 高端做网站哪家好sem技术培训
  • 网站做等保是按照什么定级别的做网站的资源哪里找
  • 免费建站网页无需登陆潍坊高端模板建站
  • 北京php网站建设软通动力外包值得去吗