Java NIO 之 Buffer
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,Clear与Rewind
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的更多相关文章
- Java NIO之Buffer(缓冲区)
Java NIO中的缓存区(Buffer)用于和通道(Channel)进行交互.数据是从通道读入缓冲区,从缓冲区写入到通道中的. 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这 ...
- JAVA NIO简介-- Buffer、Channel、Charset 、直接缓冲区、分散和聚集、文件锁
IO 是主存和外部设备 ( 硬盘.终端和网络等 ) 拷贝数据的过程. IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成. Java标准io回顾 在Java1.4之前的I/O系统中,提供 ...
- java nio之Buffer(一)
Buffer是一个包装了基本数据元素数组的对象,它以及它的子类定义了一系列API用于处理数据缓存. 一.属性 Buffer有四个基本属性: 1.capacity 容量,buffer能够容纳的最大元素 ...
- Java NIO -- 缓冲区(Buffer)的数据存取
缓冲区(Buffer): 一个用于特定基本数据类型的容器.由 java.nio 包定义的,所有缓冲区都是 Buffer 抽象类的子类.Java NIO 中的 Buffer 主要用于与 NIO 通道进行 ...
- Java NIO 之 Buffer(缓冲区)
一 Buffer(缓冲区)介绍 Java NIO Buffers用于和NIO Channel交互. 我们从Channel中读取数据到buffers里,从Buffer把数据写入到Channels. Bu ...
- 【Java nio】buffer
package com.slp.nio; import org.junit.Test; import java.nio.ByteBuffer; /** * Created by sanglp on 2 ...
- java nio之Buffer
一.JAVA NIO 是在和channel交互的时候使用的.Channel将数据读入缓冲区,然后我们又从缓冲区访问数据.写数据时,首先将要发送的数据按顺序填入缓冲区.基本上,缓冲区只是一个列表,它的所 ...
- Java NIO:Buffer、Channel 和 Selector
Buffer 一个 Buffer 本质上是内存中的一块,我们可以将数据写入这块内存,之后从这块内存获取数据. java.nio 定义了以下几个 Buffer 的实现,这个图读者应该也在不少地方见过了吧 ...
- JAVA NIO缓冲区(Buffer)------ByteBuffer常用方法
参考:https://blog.csdn.net/xialong_927/article/details/81044759 缓冲区(Buffer)就是在内存中预留指定大小的存储空间用来对输入/输出(I ...
随机推荐
- .NET Core:使用ImageSharp跨平台处理图像
一.简述 ImageSharp是一个新的跨平台2D图形API,旨在处理图像而不使用System.Drawing. 二.安装 目前ImageSharp还是处于alpha版本,所以我们需要在nuget中添 ...
- org.springframework.data.redis.serializer.SerializationException: Cannot serialize;
前言 本文中提到的解决方案,源码地址在:perfect-ssm,希望可以帮你解决问题. 问题描述 在Spring与Redis整合过程中,出现了如下报错: org.springframework.dat ...
- 《SpringMVC从入门到放肆》三、DispatcherServlet的url-pattern配置详解
上一篇我们详细解释了一下SrpingMVC的执行流程以及一些默认的配置,在Spring的思想中,就是默认大于配置.今天我们来详细的研究一下DispatcherServlet的url-pattern配置 ...
- [51nod1709]复杂度分析
给出一棵n个点的树(以1号点为根),定义dep[i]为点i到根路径上点的个数.众所周知,树上最近公共祖先问题可以用倍增算法解决.现在我们需要算出这个算法精确的复杂度.我们定义计算点i和点j最近公共组先 ...
- class 文件反编译器的 java 实现
最近由于公司项目需要,了解了很多关于类加载方面的知识,给项目带来了一些热部署方面的突破. 由于最近手头工作不太忙,同时驱于对更底层知识的好奇与渴求,因此决定学习了一下 class 文件结构,并通过一周 ...
- Effective Java 第三版——24. 优先考虑静态成员类
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Button重写onClick两种方式
实现接口和匿名内部类 下午没课,自己又继续安卓的学习,照着书上做了一个left碎片Button点击后动态加载right碎片布局的Test,准备自己再继续做一个单击左碎片的button1 加载右碎片布局 ...
- 【WebApi系列】浅谈HTTP
[01]浅谈HTTP在WebApi开发中的运用 [02]聊聊WebApi体系结构 [03]详解WebApi如何传递参数 [04]详解WebApi测试和PostMan [05]浅谈WebApi Core ...
- dedecms====phpcms 区别==[工作]
{template "content","header"}{dede:include filename="head.htm"/} ----- ...
- NSRange 用法
NSRange的定义 typedef struct _NSRange { NSUInteger location; NSUInteger length; } NSRange; NSRange是一个结构 ...