重回东软了,据说可能要做一个跟文件相关的项目,于是决定把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. Mac中Eclipse配置Maven开发环境

    1.下载Maven tar.gz包 http://maven.apache.org/download.cgi 2.解压tar包 随便一个路径都行 3.配置环境变量 bash设置~/.bash_prof ...

  2. ruby gem源更换国内源gems.ruby-china.org数据源

    gem sources -l gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/ 更新缓存 ge ...

  3. 混合文件系统(ramdisk+jffs)

    背景知识: 一.Ramdisk文件系统: 1.掉电丢失 2.读写速度高 3.数据存储到内存 二.jffs文件系统 1.掉电不丢失 2.可存储于NOR NAND,但是适用于NOR 3.数据存储于flas ...

  4. MySQL5.7.12新密码登录方式及密码策略

    在Centos6.6上安装MySQL5.7.12时,遇到了一个问题 安装后在/root目录下没有发现有.mysql_secret这个文件,所以没有没法按照官方文档上说的那样使用,这里记录下, 解决方式 ...

  5. python中关于正则表达式一

    ab+,描述一个'a'和任意个'b',那么'ab','abb','abbbbb' 正则表达式可以:1.验证字符串是否符合指定特征,比如验证是否是合法的邮件地址 2.用来查找字符串,从一个长的文本中查找 ...

  6. C#微信公众号开发 -- (六)自定义菜单事件之CLICK

    微信公众号中当用户手动点击了按钮,微信公众号会被动的向用户发送文字消息或者图文消息. 通过C#微信公众号开发 -- (五)自定义菜单创建 我们知道了如何将CLICK类型的按钮添加到自己的微信公众平台上 ...

  7. linux下apache-tomcat的安装

    一.JDK安装 1.安装JDK软件包 本例使用的JDK安装包为jdk-6u19-linux-x64.bin,该包是一个编译好的二进制可执行程序包,只需要执行即可安装. 首先进入存放JDK安装包的目录( ...

  8. LiangNa Resum

    LiangNa AnShan Street, YangPu, NY @.com OBJECTIVE: Seeking a position to contribute my skills and ed ...

  9. 向SQL2008R2导入Acess、excel数据

    一:导入Access数据 1.在sql2008查询分析 器中输入如下查询语句能查出access中的数据 SELECT * FROM OpenDataSource( 'Microsoft.Jet.OLE ...

  10. OC 消息传递机制

    消息传递(message passing)的概念是Smalltalk语言的核心原则之一,有时Smalltalk和Objective-C被称为面向消息的语言,通常“消息”一词的含义和“方法”是相同的. ...