Java NIO Buffer

  Java NIO (Non Blocking IO 或者 New IO)是一种非阻塞IO的实现。NIO通过Channel、Buffer、Selector几个组件的协同实现提升IO效率的目的。而ByteBuffer是其中最基础的一种Buffer实现。

阻塞 or 非阻塞

  阻塞/非阻塞,同步/异步是两组非常容易产生混淆的概念。

同步/异步:是从消息通信机制的划分,如果调用者在没有得到结果前“调用”不返回,则是同步的。而如果调用发出后,调用直接返回,结果由被调用者通过某种机制(通知、状态)返回,则是异步的。

阻塞/非阻塞:是站在调用者的角度,描述调用者在等待调用结果时的状态。阻塞是指,在得到返回结果前,当前线程会被一直挂起,只有在得到结果后才返回。非阻塞是指,调用不会阻塞当前线程,可能不会得到想要的结果,但会立刻返回。

以找老板签报销单为例:

如果去老板工位发现老板不在,你一直站在旁边等老板回来签字才回去,那你就是阻塞的(好蠢。。。);

如果去老板工位发现老板不在,你立马回来继续撸代码,过会又跑去看看老板在不在,如果不在又回来喝口水。。。那这个过程你就是非阻塞的(也有点蠢。。。);

而上述两个过程中,“通信机制”都是同步的。而:

如果,你跑过去找老板签字,老板说放这吧,过会老板把签好的报销单交给你,那这次交互过程就是异步的(想得美。。。);

可见JAVA NIO是非阻塞式的IO,是同步的IO机制。

Buffer的结构

Buffer通过position,limit,capacity三个变量管理内容。其中:capacity标记Buffer总容量大小;position标识当前可读或者可写的初始位置;limit标记当前可读或者可写的极限位置,当Buffer处于write模式时,limit=capacity,当切换至Read模式时,limit为对应写模式时的position。三者满足:position <= limit <= capacity;一种Buffer从写模式切换至读模式的示意如下图:

Flip,ClearRewind

Clear操作,置position=0, limit=capacity,将Buffer置于写模式;

Flip操作,置limit=last_position, position=0,将Buffer置于读模式;

Rewind操作,置position=0, limit不变,使得可以重新读取Buffer中的内容。

 

HeapByteBuffer , Direct ByteBuffer MappedByteBuffer

ByteBuffer本质是一块内存区域。对于ByteBuffer,可以通过allocate(int)和allocateDirect(int)分别分配Heap和Direct Buffer。ByteBuffer持有仅对Heap Buffer有效的一个字节型数组:

final byte[] hb;                  // Non-null only for heap buffers

可见HeapByteBuffer是直接分配在堆上的,可以简单理解为byte[]的一种封装。

而Direct Buffer不直接分配在堆上,其不受GC管理(而指向这块内存的Java对象是受GC管理的,只有GC回收了这个对象,操作系统才会释放Direct Buffer的内存空间)。

由于Direct Buffer由系统直接管理,其读写的消耗小于在堆上进行读写(减少了从系统至程序内存空间的拷贝)。实际上每次使用ByteBuffer进行读写时,都会临时开辟一段DirectBuffer(JDK实现上对其做了池化,避免了频繁创建和释放DirectBuffer带来的高系统调用消耗),将ByteBuffer中的内容拷贝进其中,再进行后续操作,多了一步Buffer间的拷贝操作。所以对于重复使用的Buffer,使用Direct Buffer的优点显而易见。

但是创建和释放Direct Buffer的代价则高于Heap Buffer(系统函数的直接调用),同时不当地使用DirectBuffer更容易引起内存泄漏。

MappedByteBuffer是一种DirectByteBuffer,而其内容是一个文件的全部或者部分映射。由于MappedByteBuffer对进行了文件进行了内存映射,避免了读写时进行write/read系统调用,所有在大文件读写方面具有极高的性能。但是其同样存在DirectByteBuffer存在的问题,同时涉及文件操作,文件的关闭也依赖于垃圾回收。

对上述三种Buffer进行测试对比,分别读写大小为1M,256M和1G的文件(过小的文件并没有性能上的明显差异),结果如下:

可见,当文件较小时三者并没有明显的性能差异。而在进行大文件的读写时MappedByteBuffer表现出了明显的性能优势。同时可以看到Direct和Heap之间并没有明显的差异。

Java NIO 之 Buffer的更多相关文章

  1. Java NIO之Buffer(缓冲区)

    ​ Java NIO中的缓存区(Buffer)用于和通道(Channel)进行交互.数据是从通道读入缓冲区,从缓冲区写入到通道中的. ​ 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这 ...

  2. JAVA NIO简介-- Buffer、Channel、Charset 、直接缓冲区、分散和聚集、文件锁

    IO  是主存和外部设备 ( 硬盘.终端和网络等 ) 拷贝数据的过程. IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成. Java标准io回顾 在Java1.4之前的I/O系统中,提供 ...

  3. java nio之Buffer(一)

    Buffer是一个包装了基本数据元素数组的对象,它以及它的子类定义了一系列API用于处理数据缓存. 一.属性 Buffer有四个基本属性: 1.capacity  容量,buffer能够容纳的最大元素 ...

  4. Java NIO -- 缓冲区(Buffer)的数据存取

    缓冲区(Buffer): 一个用于特定基本数据类型的容器.由 java.nio 包定义的,所有缓冲区都是 Buffer 抽象类的子类.Java NIO 中的 Buffer 主要用于与 NIO 通道进行 ...

  5. Java NIO 之 Buffer(缓冲区)

    一 Buffer(缓冲区)介绍 Java NIO Buffers用于和NIO Channel交互. 我们从Channel中读取数据到buffers里,从Buffer把数据写入到Channels. Bu ...

  6. 【Java nio】buffer

    package com.slp.nio; import org.junit.Test; import java.nio.ByteBuffer; /** * Created by sanglp on 2 ...

  7. java nio之Buffer

    一.JAVA NIO 是在和channel交互的时候使用的.Channel将数据读入缓冲区,然后我们又从缓冲区访问数据.写数据时,首先将要发送的数据按顺序填入缓冲区.基本上,缓冲区只是一个列表,它的所 ...

  8. Java NIO:Buffer、Channel 和 Selector

    Buffer 一个 Buffer 本质上是内存中的一块,我们可以将数据写入这块内存,之后从这块内存获取数据. java.nio 定义了以下几个 Buffer 的实现,这个图读者应该也在不少地方见过了吧 ...

  9. JAVA NIO缓冲区(Buffer)------ByteBuffer常用方法

    参考:https://blog.csdn.net/xialong_927/article/details/81044759 缓冲区(Buffer)就是在内存中预留指定大小的存储空间用来对输入/输出(I ...

随机推荐

  1. LVS三种模式分析(超详细)

    1.DR模式:(Direct Routing)直接路由模式 DR模式的网络拓扑: DR模式的工作过程: 1.当一个client发送一个WEB请求到VIP,LVS服务器根据VIP选择对应的real-se ...

  2. DOM拓展表格小练习

    涉及的知识点 DOM操作HTML页面.DOM操控表格.一些基本的事件.遍历知识.数组字符串知识.函数的作用域知识 效果图 html代码 <body><div id="con ...

  3. deeplearning.ai 构建机器学习项目 Week 1 机器学习策略 I 听课笔记

    这门课是讲一些分析机器学习问题的方法,如何更快速高效的优化机器学习系统,以及NG自己的工程经验和教训. 1. 正交化(Othogonalization) 设计机器学习系统时需要面对一个问题是:可以尝试 ...

  4. STOI补番队互测#2

    Round2轮到我出了>_<(目测总共10人参加 实际共七人) 具体情况: #1: KPM,360 #2:ccz181078,160 #3:child,150 可惜KPM没看到第一题样例里 ...

  5. HDU1097-A hard puzzle-快速幂+取模

    快速幂: 代码: kuaisumi(ll a,ll b){      ll ans=;      while(b){          ==){              ans=ans*a;     ...

  6. HDU5135 dfs搜索 枚举种数

    Little Zu Chongzhi's Triangles Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 ...

  7. div排版+文档流+定位秘诀

    由于没有找到自己认为完整的关于普通流.浮动和绝对定位的中文文章,于是鼓起勇气决定自己来写篇. 在普通流中的 Box(框) 属于一种 formatting context(格式化上下文) ,类型可以是 ...

  8. 使用 SVG 和 JS 创建一个由星形变心形的动画

    序言:首先,这是一篇学习 SVG 及 JS 动画不可多得的优秀文章.我非常喜欢 Ana Tudor 写的教程.在她的教程中有大量使用 SVG 制作的图解以及实时交互 DEMO,可以说教程的所有细枝末节 ...

  9. zookeeper基本讲解及基本命令和配置 (转)

    一.ZooKeeper概述 ZooKeeper是一种为分布式应用所设计的高可用.高性能且一致的开源协调服务,是Google的Chubby一个开源实现,是Hadoop和Hbase的重要组件,它提供了一项 ...

  10. UE4 分层材质 Layerd Materials

    在UE4中最正规的材质制作流程就像: 建立新材质,并将其调整为达至完美. 在内容浏览器中,建立新材质函数,并将所有材质函数节点复制/粘贴到其中. 将网络连接到新的 Make Material Attr ...