前言

  Java I/O功能封装的很好,使用起来很方便,就是刚开始学的时候,如果不了解装饰器模式,会被他繁多的类给吓到。用多了也就习惯了,而且现在有很多实用的封装良好的实用类,可直接读写整个文件。开发者不知道底层实现细节,也可以灵活使用,这是封装的一大优点。但是,作为一名软件开发人员,对其所使用的代码不能仅仅停留在熟悉功能特性上,最好对其实现原理也要有一定了解。

注:本文引用了部分外文内容,并根据自己的理解进行了翻译,连接将在文末贴出。

缓冲处理、内核空间vs用户空间

--------------------------------------外文引用内容Begin(已翻译)----------------------------------------------------------------

  缓冲,以及如何处理缓冲是所有IO的基本内容。术语"I/O"(输入输出)指的不过就是从缓冲区移入或移除数据。通常,进程执行I/O操作的方式是,向操作系统发送请求,请求其填充自己的缓冲区(或者把自己缓冲区的内容写出)。这就是I/O这个概念的全部内容。要实现这些传输操作,操作系统底层的实现非常复杂。但是在概念上,本文所要讲述的内容则非常直白。

  

  注意:User space和Kernel space 都属于内存。内存分为两个区,用户区和系统区(内核区)。

  上图简要展示了,块数据如何从外部源头(比如硬盘)移入到进程的内存空间的过程。首先,这个进程通过系统调用read(),请求填充自己的缓冲区。这将导致内核发送一个命令到磁盘控制器,使其从磁盘中抓取数据。磁盘控制器通过DMA把数据直接写入到内核空间缓冲区,这个过程不需要CPU干预。一旦磁盘控制器完成了填充数据的任务,内核就将数据从内核空间的临时缓冲区转移到进程指定的缓冲区内。

  有一件事需要注意,内核会试图缓冲或者说预加载一些数据,所以有可能进程所请求的数据已经在内核空间里了。如果这样的话,进程请求的数据,只需要从内核缓冲区拷贝一份即可。如果数据不在内核空间内,则在内核获取数据到内存的过程中,此进程将被挂起。

--------------------------------------外文引用内容End(已翻译)-------------------------------------------------------------------

从上述内容可知:

  • Java的读写操作,底层由C/C++实现。而不是直接与OS接触
  • C/C++读写操作,需要OS服务
  • 内核自带缓冲,会过分加载
  • 如果内存中没有数据的缓冲,读写操作将阻塞当前线程(OS会帮你挂起线程)

DMA

  DMA(Direct Memory Access,直接内存存取)是I/O设备控制方式的一种。我个人认为它们的主要差别在于CPU的参与I/O控制的程度

I/O设备控制方式有:

  • 程序I/O方式——CPU需反复检查
  • 中断I/O方式——每完成一个字节的读写,通知CPU
  • DMA方式——每完成一个块(多字节)的读写,通知CPU
  • I/O通道方式(暂不了解)

在DMA读写I/O设备的时候,CPU不会被影响,它可以继续执行。注意!这里能继续执行,指的是CPU可以继续运行,而此I/O操作的线程已经被挂起,不参与CPU调度。I/O操作完成后,该线程才被唤醒,参与调度(加入就绪队列,等待时间片)

系统调用

  系统调用是应用程序间接调用OS函数的方式。C语言有提供与系统调用相对应的库函数。这里就是read、write。 

BufferedXXStream

  注意,对于Java来说,系统调用的开销是比较大的。首先读写操作要触发的是本地方法read0,readBytes,write0,writeBytes,这里JNI需要一定开销。还有就是每产生一个系统调用,就可能产生上千个机器指令,这种开销是不容小觑的。所以,我们要尝试减少系统调用。那有人就会问了,不行啊,我数据又不能缺斤少两,少读少写肯定出问题,怎么减少调用?这不是很好解决吗,每次多读写一点,调用的次数不就少了嘛。而BufferedXXStream就是这么用的,例如,BufferedInputStream的read无参方法只读取一个字节,而实际上BufferedInputStream默认读取了8kb,这些数据用字节数组保留。

     对了,如果对上图,不是很理解,可以看看这张。

   即运行时,有一个对象BufferedInputStream,其调用一次read()方法,数据保留到buf数组中。

参考文献  

How Java I/O Works Internally at Lower Level?(外网)

【杂谈】Java I/O的底层实现的更多相关文章

  1. 如何精确地测量java对象的大小-底层instrument API

    转载: 如何精确地测量java对象的大小-底层instrument API 关于java对象的大小测量,网上有很多例子,大多数是申请一个对象后开始做GC,后对比前后的大小,不过这样,虽然说这样测量对象 ...

  2. Java进阶(二十五)Java连接mysql数据库(底层实现)

    Java进阶(二十五)Java连接mysql数据库(底层实现) 前言 很长时间没有系统的使用java做项目了.现在需要使用java完成一个实验,其中涉及到java连接数据库.让自己来写,记忆中已无从搜 ...

  3. 《Java并发编程的艺术》Java并发机制的底层实现原理(二)

    Java并发机制的底层实现原理 1.volatile volatile相当于轻量级的synchronized,在并发编程中保证数据的可见性,使用 valotile 修饰的变量,其内存模型会增加一个 L ...

  4. 【java并发编程艺术学习】(三)第二章 java并发机制的底层实现原理 学习记录(一) volatile

    章节介绍 这一章节主要学习java并发机制的底层实现原理.主要学习volatile.synchronized和原子操作的实现原理.Java中的大部分容器和框架都依赖于此. Java代码 ==经过编译= ...

  5. Java 并发系列之二:java 并发机制的底层实现原理

    1. 处理器实现原子操作 2. volatile /** 补充: 主要作用:内存可见性,是变量在多个线程中可见,修饰变量,解决一写多读的问题. 轻量级的synchronized,不会造成阻塞.性能比s ...

  6. Java并发机制的底层实现原理之volatile应用,初学者误看!

    volatile的介绍: Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现 ...

  7. java常用集合框架底层实现简介与注意点

    Collection: ArrayList:1:底层实现是数组,默认长度是10.2:add(),判断是否数组越界,是数组扩容为原来的两倍.3:remove(),copy数组,size-1,释放空虚的空 ...

  8. 再学Java 之 HashMap的底层实现

    今天参加欢聚时代的面试,我说我自己依靠自己的理解重新实现过HashMap.描述我自己的实现思想后,面试官问“hashmap”底层如果用数组不是效率比较低吗,不是更应该用红黑树吗?我一下子就蒙了.用数组 ...

  9. JAVA框架 Spring AOP底层原理

    一:AOP(Aspect Oriented Programming)面向切面编程. 底层实现原理是java的动态代理:1.jdk的动态代理.2.spring的cglib代理. jdk的动态代理需要被代 ...

随机推荐

  1. (最长上升子序列 并记录过程)FatMouse's Speed -- hdu -- 1160

    http://acm.hdu.edu.cn/showproblem.php?pid=1160 FatMouse's Speed Time Limit: 2000/1000 MS (Java/Other ...

  2. MySQL查询练习(45道)

    题目:设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教师信息表(Teacher). 四个表的结构分别如表1-1的表(一)~表(四)所示,数据如表1 ...

  3. noip第15课作业

    1. 累加求和 给定n(1<=n<=100),用递归的方法计算1+2+3+4+5+......+(n-1)+n. 输入:一个大于等于1的整数. 输出:输出一个整数. [样例输入] 5 [样 ...

  4. 关于建立MySQL数据库,中文出现乱码问题

    MySQL的ini文件中的默认编码设置utf-8不用改 loose-default-character-set = utf-8 注意:需要改动部分 1.如图所示 建立schema时改变字符编码 改变为 ...

  5. shell 网络状态查询 ping curl telnet

    ping curl telnet python -m SimpleHTTPServer

  6. 数据统计--union all 执行多条sql

    需求--统计hive某张表type字段不同取值的数据量 我们已知某张表的type的取值是1,2,3,4,5,想要统计不同type的数据量,并清晰的展现出来.可以通过union all 的方式,sql如 ...

  7. poj 2046&&poj1961KMP 前缀数组

    Power Strings Time Limit: 3000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Jav ...

  8. 2.Django模型

    ORM简介 MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库 ORM是“对象-关系-映射”的简称 ...

  9. nginx实现unigui群集

    nginx实现unigui群集 在笔者写此文的时候,UNIGUI1.50.x的版本已经发布,其提供的HyperServer已经支持群集. 有网友还专门为此做了群集方面的测试: 从上图可以看出:群集总共 ...

  10. FastReport报表设计(仔细看)

    FastReport报表设计 2011-06-16 16:56:19|  分类: 系统开发|举报|字号 订阅     下载LOFTER我的照片书  |     目录 5.1 前言 5.2 基本概念及操 ...