Buffer的工作方式
1、Buffer的工作方式
前面《java NIO的工作方式》介绍了Selector检测到通信信道I/O有数据传输时,通过select()方法取得SocketChannel,将数据读取或写入Buffer缓冲区,下面讨论Buffer如何接受和写出数据。通过查看JDK源码可知道,Buffer的构造函数
Buffer(int mark, int pos, int lim, int cap) { // package-privateif (cap < 0)throw new IllegalArgumentException();this.capacity = cap;limit(lim);position(pos);if (mark >= 0) {if (mark > pos)throw new IllegalArgumentException();this.mark = mark;}}
Buffer可以简单的理解为一组基本数据类型的元素列表,它通过几个变量来保存这个数据的当前位置状态,也就是四个索引
private int mark = -1;private int position = 0;private int limit;private int capacity;
表1-1 Buffer中的索引及说明
在实际操作数据时他们关系如图1-2所示。
我们通过ByteBuffer.allocate(11)方法创建一个11个byte的数组缓冲区,初始状态如图1-2所示,position的位置为0,capacity和limit默认都是数组长度。当我们写入5个字节时位置变化如图1-3所示。
注意:我们查看ByteBuffer.allocate()方法源码可知,执行的是以下代码
ByteBuffer(int mark, int pos, int lim, int cap, // package-privatebyte[] hb, int offset){super(mark, pos, lim, cap);this.hb = hb;this.offset = offset;}public static ByteBuffer allocate(int capacity) {if (capacity < 0)throw new IllegalArgumentException();return new HeapByteBuffer(capacity, capacity);}
返回的是HeapByteBuffer又是ByteBuffer的子类,并且在HeapByteBuffer的构造方法中执行的是这样一个语句:
super(-1, 0, lim, cap, new byte[cap], 0);
也就是说调用的还是ByteBuffer中的构造方法,包范围内使用。这个方法做了如下工作,首先调用Buffer的构 造方法,依次初始化mark、position、limit、capacity,然后初始化ByteBuffer的属性byte数组,接着初始 offset,这样使用allocate方法就可以构造出一个ByteBuffer对象了。
这时我们需要将缓冲区的5个字节数据写入Channel通信信道,所以我们调用byteBuffer.flip()方法,查看源码得知
public final Buffer flip() {limit = position;position = 0;mark = -1;return this;}
limit走到position的位置,而position回到了初始位置0,倒转了缓冲区,数组的状态发生如图1-4所示的变化。
这时底层操作系统就可以从缓冲区中正确读取这5个字节数据并发送出去了。在下一次写数据之前我们在调一下clear()方法,缓冲区的索引状态又回到初始位置。
public final Buffer clear() {position = 0;limit = capacity;mark = -1;return this;}
这里还要说明一下mark,当我们调用mark()方法时,它将记录当前position的前一个位置,当我们调用reset时,position将恢复mark记录下来的值。还有一点需要说明,通过Channel获取I/O数据首先要经过操作系统的Socket缓冲区再将数据复制到Buffer中,这个操作系统缓冲区就是底层的TCP协议关联的RecvQ或SendQ队列,从操作系统缓冲区到用户缓冲区复制数据比较耗性能,Buffer提供了另外一种直接操作操作系统缓冲区的方式,即ByteBuffer.allocateDirector(size),
public static ByteBuffer allocateDirect(int capacity) {return new DirectByteBuffer(capacity);}
这个方法返回的DirectorByteBuffer就是与底层存储空间关联的缓冲区,它通过Native代码操作非JVM堆的内存空间。每次创建或者释放的时候都调用一次System.gc()。注意,在使用DirectorByteBuffer时可能会引起JVM内存泄露问题。DirectByteBuffer和Non-Direct Buffer(HeapByteBuffer)对比如图1-5所示。
转载于:https://www.cnblogs.com/wcyBlog/p/4719352.html
Buffer的工作方式相关推荐
- 并行接口电路8255A的基本使用——三种工作方式的时序图的具体讲解
文章目录 概述 内部结构图和具体引脚功能 端口A 端口B![在这里插入图片描述](https://img-blog.csdnimg.cn/20210607164952661.png) 端口C 与处理器 ...
- ZYNQ 7000 USB HS启动流程和工作方式
目录 1.USB数据结构 2.USB设备启动流程和工作方式 (1).通过ID查找USB配置信息UsbConfigPtr (2).将USB配置信息UsbConfigPtr挂接到XUsbPS对象实例Usb ...
- TLB 结构和工作方式
TLB: TLB 即 Translation Lookaside Buffer ,根据功能可以译为快表,直译可以翻译为旁路转换缓冲,也可以把它理解成页表缓冲. 其中每一行都保存着一个由单个PTE(Pa ...
- LVS原理详解(3种工作方式8种调度算法)--老男孩
一.LVS原理详解(4种工作方式8种调度算法) 集群简介 集群就是一组独立的计算机,协同工作,对外提供服务.对客户端来说像是一台服务器提供服务. LVS在企业架构中的位置: 以上的架构只是众多企业里面 ...
- 30岁找不到工作很绝望_计算机为绝望的新编码员工作方式的快速指南
30岁找不到工作很绝望 by Danielle Ormshaw 丹妮尔·欧姆肖(Danielle Ormshaw) 计算机为绝望的新编码员工作方式的快速指南 (The quick guide to t ...
- 超越Android:Kotlin在后端的工作方式
by Adam Arold 亚当·阿罗德(Adam Arold) 超越Android:Kotlin在后端的工作方式 (Going Beyond Android: how Kotlin works on ...
- 开源许可证 如何工作_开源许可证的工作方式以及如何将其添加到您的项目中...
开源许可证 如何工作 by Radu Raicea 由Radu Raicea 开源许可证的工作方式以及如何将其添加到您的项目中 (How open source licenses work and h ...
- 《编译与反编译技术实战》——2.1节编译器、解释器及其工作方式
本节书摘来自华章社区<编译与反编译技术实战>一书中的第2章,第2.1节编译器.解释器及其工作方式,作者刘晓楠 陶红伟 岳 峰 戴超,更多章节内容可以访问云栖社区"华章社区&quo ...
- Makefile —— Makefile的规则是什么?make是如何工作的?make的工作方式是什么?
#1.Makefile的规则: # target... : prerequisites... # command target是:[目标文件:包含执行文件edit与中间目标文件(*. ...
最新文章
- sql 相加_SQL-多表查询
- 布隆过滤器速度_布隆过滤器的分析和实现
- poj3687Labeling Balls
- redis 计数器 java_Redis 实践汇总和使用建议。
- 数据类型转换_注意事项
- Oracle之同义词,DBLINK,表空间
- Spring--@within和@target的区别
- linphone-android移植
- Android学习笔记(八)XML文档的解析
- java 树形菜单遍历_java实现遍历树形菜单方法——service层
- 快手诉“短视频人气助手”软件不正当竞争:索赔100万元
- Linux安全加固--系统相关
- OpenCV3 install tutorial for Mac
- 【QT】Qaction和触发函数建立连接的方法
- 如何以CustomValidator搭配jQuery AJAX进行Server端验证(转)
- mysql sqlyog 备份计划_SqlYog 自动备份数据库
- Oracle | oracle11g安装环境变量配置
- 500个爆文标题_爆文标题创作思路——来自100个10W+的标题的总结
- jqGrid设置三级表头和表头合并
- 嵌入式开发培训多长时间?嵌入式课程怎么学?