重回东软了,据说可能要做一个跟文件相关的项目,于是决定把Java NIO的内容再捡起来,看看。

为什么要使用NIO,其实在低连接数的情况下,NIO的性能是要低于IO的;但是在高并发的情况下,确实NIO性能好得多;因为IO是会为为每一个连接都分配一个线程/进程进行处理,NIO则只是使用一个线程/进程,通过系统地select机制进行轮询获取请求信息;

默认情况下,设备控制器不能实现DMA(directional Memory Access),去操作user space,但是经过虚拟内存,已经可以实现了;虚拟内存就是将内核空间地址到物理地址的映射(map),供user space使用;

IO的基本概念就是buffer的处理,所谓的input/outputqish1其实就是数据从buffer中放入移出;

进程使用的是user space,发送一个read命令到内核,通过buffer(内存空间)将命令以及命令数据发送到kenal space,kenal space将命令进行处理,从硬盘中去读数据,硬盘通过DMA(不需要经过CPU)直接将数据写入到kernal memory,kernal space再将数据进行重新组装(因为从设备过来的数据data-block,需要kernal space进行处理拆包打包后封装成byte buffer),并拷贝到临时的buffer中发送到user space中;

在现代操作系统中引入了虚拟内存(Virtual Memory)的概念,VM的好处两点:多个虚拟地址空间可以映射到同一个物理内存(比如user space以及kernal space都可以访问物理的内存空间);虚拟空间可以大于物理内存空间(超出的可以放置到硬盘的交换区);这样,作为内存,他的定位就是(沦为)物理硬盘的一个缓存,根据需要的内容置换到内存中去;

有了虚拟内存之后,上面介绍的操作中"并拷贝到临时的buffer中发送到user space中"的步骤就可以省略了,因为虚拟地址可以让user space和kernal space共享相同的物理内存地址,只要他们都是访问虚拟地址;userspace也可以访问到kernalspace组装好的bytebuffer;但是因为这样意味着user space可以直接读取设备(比如硬盘)设置的内存空间,所以这意味着需要对于内存进行分页(物理内存以及虚拟内存,一般两者分页大小一样);通常情况下,每页的大小是block的倍数,每个物理扇片的大小是521btye,内存分页大小为1024,2048以及4096;

在CPU和内存之间其实还有一个组件,称之为MMU,Memory Management Unit,专门用于将虚拟地址转换定位到物理地址,他负责定位对应"页";当需要的页并不在当前内存中,就会触发一个fault page,如果请求的虚拟地址是在物理硬盘正存放的,那么需要把所需的页从硬盘中取出来放入到内存中;如果请求的地址并不存在,那么,这个进程将会被杀死(kill);在这个过程中,可能是需要进行置换(stole)一部分当前内存的页到物理硬盘中,这个时候就需要对这些页进行复制然后传入到硬盘中;

其实所谓的"虚拟空间可以大于物理内存空间"是指虚拟空间他自己另外造了一套体系,实现虚拟空间和内存,虚拟空间和硬盘通过页的映射;所以已经不再仅仅局限于物理内存的概念了;物理内存空间的角色更像是虚拟空间的一个物理缓存;

并不是所有的设备都是采用block方式进行传输,比如CD机,打印机端口,网络端口等设备就是采用流(stream)的方式;stream的方式其实速度是比block方式要慢,一般用于间歇性通信情况;对于stream的接受有两种方式,一种是nonblock方式,这种方式是让进程去监听是否有可用的流准备好了(没有,进程可以释放做别的事情,有,进程则专职处理流);还有一种方式就是readiness selection,操作系统将会被通知,告知有流准备好了,前者是进程主动监控是否有可用流;后者则是通知机制(草莓园与园丁模式);

MappedByteBuffer使用:

FileInputStream fis = new FileInputStream(sourcePath);

FileOutputStream fos = new FileOutputStream(targetPath);

FileChannel fc = fis.getChannel();

FileChannel out = fos.getChannel();

MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());

out.write(mbb);

out.close();

,limit就是本来长度;如果你使用flip之后,将会导致limit=position=0;到最后ByteBuffer的塌陷;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Java NIO回炉的更多相关文章

  1. 源码分析netty服务器创建过程vs java nio服务器创建

    1.Java NIO服务端创建 首先,我们通过一个时序图来看下如何创建一个NIO服务端并启动监听,接收多个客户端的连接,进行消息的异步读写. 示例代码(参考文献[2]): import java.io ...

  2. 支撑Java NIO 与 NodeJS的底层技术

    支撑Java NIO 与 NodeJS的底层技术 众所周知在近几个版本的Java中增加了一些对Java NIO.NIO2的支持,与此同时NodeJS技术栈中最为人称道的优势之一就是其高性能IO,那么我 ...

  3. JAVA NIO学习笔记1 - 架构简介

    最近项目中遇到不少NIO相关知识,之前对这块接触得较少,算是我的一个盲区,打算花点时间学习,简单做一点个人学习总结. 简介 NIO(New IO)是JDK1.4以后推出的全新IO API,相比传统IO ...

  4. Java NIO概述

    Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然 Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Se ...

  5. JAVA NIO Socket通道

      DatagramChannel和SocketChannel都实现定义读写功能,ServerSocketChannel不实现,只负责监听传入的连接,并建立新的SocketChannel,本身不传输数 ...

  6. JAVA NIO FileChannel 内存映射文件

      文件通道总是阻塞式的. 文件通道不能创建,只能通过(RandomAccessFile.FileInputStream.FileOutputStream)getChannel()获得,具有与File ...

  7. java nio系列文章

    java nio系列教程 基于NIO的Client/Server程序实践 (推荐) java nio与并发编程相关电子书籍   (访问密码 48dd) 理解NIO nio学习记录 图解ByteBuff ...

  8. Java NIO (转)

    Java NIO提供了与标准IO不同的IO工作方式: Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(B ...

  9. Java NIO使用及原理分析(1-4)(转)

    转载的原文章也找不到!从以下博客中找到http://blog.csdn.net/wuxianglong/article/details/6604817 转载自:李会军•宁静致远 最近由于工作关系要做一 ...

随机推荐

  1. Redis学习手册(Hashes数据类型)

    一.概述: 我们可以将Redis中的Hashes类型看成具有String Key和String Value的map容器.所以该类型非常适合于存储值对象的信息.如Username.Password和Ag ...

  2. Labview 中的类

    一.创建一个空的类 在 LabVIEW 工程窗口里,鼠标右键菜单的新建栏中有一项,是创建类.类的结构和 LabVIEW 工程库是比较相近的:类的名字也作为名字空间:也可以为类中的 VI 设置访问权限等 ...

  3. qsettings 中文键值 注释 支持

    #ifndef SETTINGS_H #define SETTINGS_H #include <QString> #include <QVariant> class QSett ...

  4. MVC - HtmlHelper类

    传统的Html元素不能和服务端数据进行绑定 HtmlHelper类提供了一系列的方法来生成Html元素 并可以实现与数据绑定在一起 然后生成Html Html.BeginForm(actionName ...

  5. android自定义View之NotePad出鞘记

    现在我们的手机上基本都会有一个记事本,用起来倒也还算方便,记事本这种东东,如果我想要自己实现,该怎么做呢?今天我们就通过自定义View的方式来自定义一个记事本.OK,废话不多说,先来看看效果图. 整个 ...

  6. 关于ProgressBar的美化问题

    Android自带的ProgressBar其实也算不上丑陋,但是如果所有的App都使用一个模式的ProgressBar,那么估计用户就要崩溃了,打开任何一个App,擦,进度条都一模一样..有鉴于此,我 ...

  7. sqlServer 求当前周的第一天和最后一天,当前月的第一天和最后一天,前三个月的第一天和今天

    ---当前周的第一天 ),DATEADD(day,-(DATEPART(weekday,GETDATE())-),GETDATE()) , )as'周一', CONVERT(varchar(),DAT ...

  8. MongoDB 2.6.x 的安装部署

    1. 下载mongodb 2.6.x版本的zip包,在D盘创建目录MongoDB,解压缩到D:\MongoDB目录. 创建数据库目录D:\MongoDB\data,接下来打开命令行窗口,切换到D:\M ...

  9. ACM——A + B Problem (2)

    A + B Problem (2) 时间限制(普通/Java):1000MS/3000MS          运行内存限制:65536KByte总提交:2600            测试通过:137 ...

  10. js自执行函数表达式

    // 下面2个括弧()都会立即执行 (function () { /* code */ } ()); // 推荐使用这个(function () { /* code */ })(); // 但是这个也 ...