当前位置: 首页 > 编程日记 > 正文

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

相关文章:

PHP 相关配置

2019独角兽企业重金招聘Python工程师标准>>> 1. php-fpm的pool 编辑php-fpm配置文件php-fpm.convim /usr/local/php/etc/php-fpm.conf //在[global]部分增加以下内容include etc/php-fpm.d/*.conf # 相当与Nginx的虚拟主机文件 “vhost” 的配置 创建存放pool配置…

学生教育云平台登录入口_湖南省教育云平台登录入口

湖南省教育云平台官方网站http://www.hnzyzx.com/&#xff0c;好学网的中小学频道为学友整理。 湖南省教育网&#xff1a; 点击登录&#xff1a; 湖南省教育云平台登录系统 下方为湖南信息教育云平台登录入口图示&#xff1a;安全教育平台学生姓名错误处理方法…

flash中制的SWC组件怎样导入到flex中使用

flash中制的SWC组件怎样导入到flex中使用2010-04-30 11:18在使用FLASH导出SWC组件文件后&#xff0c;放入项目的LIB文件夹&#xff0c;然后要用实例化一个对象才能进行时操作使用&#xff0c; 但要记得的是&#xff0c;导出时候要再导出的组件处勾选链接&#xff0c;勾选为AS导…

开源智能手机 Librem 5 跳票了,推迟至第3季度发布

百度智能云 云生态狂欢季 热门云产品1折起>>> 由 Purism 公司打造的开源智能手机 Librem 5 原计划于2019年4月正式发布。但根据官方最新的消息&#xff0c;Librem 5 将推迟至2019年第3季度发货。 根据之前的消息&#xff0c;Librem 5 的预售价为 599 美元。 Librem …

js 获取URL后面的参数

1、有时间由于缓存问题&#xff0c;用PHP可能就不是太好处理&#xff0c;所以可以用客户端进行URL的处理 如下&#xff1a;js 获取URL后面的参数 <script> function getUrlParam(name) { //获取url参数 var reg new RegExp("(^|&)" name "([^&…

机械键盘恢复出厂fn_黑爵毛茸茸系列机械键盘评测

写在前面之前试用过黑爵的巧克力键盘&#xff0c;给我留下了挺不错的使用体验&#xff0c;不仅外观设计上好看&#xff0c;原厂Cherry轴体手感也不错&#xff0c;这次有幸体验到黑爵新品毛茸茸系列键盘实属荣幸。开箱学弟这次拿到的键盘是Cherry青轴&#xff0c;可能是快递有些…

centos防火墙端口配置

增加防火墙配置&#xff0c;允许8080端口&#xff1a; # vi /etc/sysconfig/iptables 在允许ssh的下面增加一条&#xff1a; -A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT 保存&#xff0c;重启iptables服务 &#xff1a; # service iptables restart…

实时智能决策引擎在蚂蚁金服风险管理中的实践

摘要&#xff1a;以“数字金融新原力(The New Force of Digital Finance)”为主题&#xff0c;蚂蚁金服ATEC城市峰会于2019年1月4日上海如期举办。金融智能专场分论坛上&#xff0c;蚂蚁金服数据技术专家王修坤做了主题为《实时智能决策引擎在蚂蚁金服风险管理中的实践》的精彩…

JAVA如何检测GC日志

只需要在JAVA程序运行的时候&#xff0c;加上VM参数就可以。像下面这样: -XX:PrintGCDetails 更具体的请参考: http://flash520.blog.163.com/blog/static/34414475201063041157163/ 转载于:https://www.cnblogs.com/bestchenwu/archive/2011/11/26/9655409.html

eclipse c语言_如果你的电脑是windows7/10的环境,用什么编译器学习C语言好?

既然问题已经限制了Windows环境&#xff0c;那么就不再推荐Linux环境下的编译器了&#xff0c;虽然在Linux环境进行C语言的编程会比Windows可以更好的掌握一些基础知识&#xff0c;自己动手gcc,写makefile文件了解编译&#xff0c;链接的过程。下面对windows环境C语言开发IDE进…

Apache Tomcat 7.0.93 发布,开源 Java Web 应用服务器

Apache Tomcat 7.0.93 已发布&#xff0c;Tomcat 是 Java Servlet、JavaServer Pages、Java 表达式语言和 Java WebSocket 技术的开源实现&#xff0c;是一个免费的开放源代码的 Web 应用服务器。 与 7.0.92 相比&#xff0c;该版本包含许多 bug 修复和改进。有以下值得关注的变…

C# using 语法说明

using 关键字有两个主要用途&#xff1a; (一).作为指令&#xff0c;用于为命名空间创建别名或导入其他命名空间中定义的类型。 (二).作为语句&#xff0c;用于定义一个范围&#xff0c;在此范围的末尾将释放对象。using指令 ①允许在命名空间中使用类型&#xff0c;这样&…

多行表头_多行表头数据汇总你怎么操作?手动复制粘贴?OUT!用VBA1分钟完成

前景提要(文末提供源码下载)发现小伙伴们的数据结果真的好复杂&#xff0c;不昨天才分享过有多行表头的数据如何汇总合并&#xff0c;今天就有小伙伴反馈&#xff0c;他的数据虽然是有多行表头的&#xff0c;但是又有一些数据没有多行表头&#xff0c;那么在进行批量数据汇总的…

VirtualBox上Ubuntu 共享文件夹

1. virtualbox 菜单栏中设备--》共享文件夹&#xff0c;添加一个共享文件夹&#xff0c;比如共享文件夹路径是D:/share&#xff0c;共享文件夹名称是share。 2. 进入虚拟Ubuntu&#xff0c;在命令行终端输入&#xff1a; sudo mkdir /mnt/sharesudo mount -t vboxsf share /mnt…

tinyMCE

TinyMCE是一个轻量级的基于浏览器的所见即所得编辑器&#xff0c;由JavaScript写成。它对IE6和Firefox1.5都有着非常良好的支持。 功能方面虽然不能称得上是最强&#xff0c;但绝对能够满足大部分网站的需求&#xff0c;并且功能配置灵活简单。另一特点是加载速度非常快&#x…

监管大屏系统_高速公路监管系统大屏可视化

0x00 项目背景该项目用于高速公路监管。高速公路监管包括&#xff1a;高速公路的设备运行情况&#xff0c;设备维护情况&#xff0c;道路维护情况&#xff1b;交通流量分析&#xff0c;交通拥堵分析&#xff0c;拥堵溯源&#xff1b;事故分析&#xff0c;事件信息发布等。0x01设…

Android(java)学习笔记96:layout_weight使用注意事项

1. android:layout_weight使用说明&#xff1a; layout_weight是权重的意思&#xff0c;也就是各个控件所占的比重&#xff0c;用在LinearLayout布局中。当我们使用layout_weight的时候&#xff0c;layout_width和layout_height有三种表示方法 2. android:layout_weight使用之 …

41.uniq命令

uniq命令&#xff1a; 选项&#xff1a;-c:显示每行的重复次数&#xff1b;-u:仅显示未曾重复过的行&#xff1b;-d:仅显示重复过的行&#xff1b; 实例&#xff1a; 转载于:https://blog.51cto.com/itxuezhe/2354162

[JS-JQuery]基础

<noscript> If you see this message, your web browser doesnt support JavaScript or JavaScript is disabled. Please enable JavaScript in your browser settings so Newegg.com can function correctly.</noscript> $(tr:odd) //选择表格的奇数行$(div:visi…

位置偏移问题 绘制_AutoCAD教程之绘制螺栓连接组合图

螺栓、螺母是机械连接件中最为常用的标准件&#xff0c;螺栓连接通常需要组合在一起。下面我们以绘制螺栓连接组合件为例&#xff0c;学习在AutoCAD 2019中移动、复制、旋转等操作的应用方法。1. 新建文件及图层新建一个“无样板公制”文件&#xff0c;新建粗实线、细实线、中心…

spring mvc 控制器方法传递一些经验对象的数组

由于该项目必须提交一个表单&#xff0c;其中多个对象,更好的方法是直接通过在控制器方法参数的数组。 因为Spring mvc框架在反射生成控制方法的參数对象的时候会调用这个类的getDeclaredConstructor方法来获得构造函数, 可是一直报NoSuchMethodException的异常。 依据这种方法…

sendmail configuration on HP-UX

使用mailx 发送邮件mailx -s "Msg title here" xxxxxx.comhello,this is the mail body<--------邮件正文. <-----------------一个点&#xff0c;表示正文结束EOT<--------------上面输入点之后&#xff0c;系统自动出现EOT&#xff0c;表示邮件输入完毕-s…

数据齿轮(DataGear)数据库管理系统 v1.1.1 发布

数据齿轮&#xff08;DataGear&#xff09;数据库管理系统v1.1.1版本发布&#xff0c;此版本是v1.1版本的紧急BUG修复版本&#xff0c;更新内容如下&#xff1a; 修复&#xff1a;修复集成软件包在JRE8及以上版本无法正常运行的BUG&#xff1b;数据齿轮&#xff08;DataGear&am…

带哨兵节点的链_【算法导论】10.2不带哨兵节点和带哨兵节点的双向链表

不带哨兵节点的双向链表即一般的双向链表&#xff0c;有一个头指针指向第一个节点&#xff0c;每个节点有key值和两个指针next和pre&#xff0c;分别指向前后相邻的节点&#xff0c;头结点的preNULL&#xff0c;尾节点的nextNULL&#xff0c;比较明了&#xff0c;但是也有麻烦的…

Android环境结构--安装Eclipse错

在学习安卓第一步。成立了一个开发环境。经验&#xff0c;知道&#xff0c;所以这一步是不容易&#xff0c;因为你觉得&#xff0c;我可能是太幸运了。我见到 题。 首先&#xff0c;安装Eclipse的时候。 【Problem 1】 【问题原因】&#xff1a; &#xff08;1&#xff09; 安装…

ThinkPHP的标签制作

thinkphp的默认标签解析器在Lib/Template/TagLib/TagLibCx.class中里面定义了常用的volist php 等常用thinkphp的标签这里笔者在这个类中添加一个<category>的标签解析标签格式&#xff1a;<category parentid0 ><{$cat.catname}></category>标签作用&…

Go进阶:反射3定律

各位学习Go语言的朋友&#xff0c;周末好&#xff0c;这次跟大家聊一聊Go语言的一个高级话题&#xff1a;反射。 这篇文章是从我过去的学习笔记修改来的&#xff0c;内容主要来自Go Blog的一篇文章《The law of reflection》。 这篇文章主要介绍反射和接口的关系&#xff0c;解…

qlabel可以选中吗_Qt QLabel详解

Qt QLabel详解Qt QLabel详解一、QLabel常用方法1. QLabel设置文本内容ui.label->setText(QStringLiteral("测试中文\n"));2. QLabel设置颜色通过设计器里面的改变样式进行设置&#xff1a;同时可以设置字体、文本对齐方式、背景图片color: rgb(255, 85, 0);backgr…

数据库种类 以及优缺点

1.MySQL MySQL是最受欢迎的开源SQL数据库管理系统&#xff0c;它由 MySQL AB开发、发布和支持。MySQL AB是一家基于MySQL开发人员的商业公司&#xff0c;它是一家使用了一种成功的商业模式来结合开源价值和方法论的第二代开源公司。MySQL是MySQL AB的注册商标。 MySQL是一个快速…