Java NIO读书笔记 -- (二)简介

I/O 的重要性

I/O操作比在内存中处理数据所需时间更长,即CPU处理速度远远大于I/O等待时间

Java I/O的重要性

多数 Java 应用程序已不 再受 CPU 的束缚(把大量时间用在执行代码上), 而更多时候是受 I/O 的束缚(等待数据传输)

NIO出现的意义

Java I/O的缺点

  1. 大多数情况下,Java 应用程序并非真的受着 I/O 的束缚。操作系统并非不能快速传送数据;相反,是 JVM 自身在 I/O 方面效率欠佳。
  2. 操作系统与 Java 基于流的 I/O 模型有些不匹配。 操作系统要移动的是大块数据(缓冲区), 这往往是在硬件直接存储器存取 (DMA)的协助下完成的。
  3. JVM 的 I/O 类喜欢操作小块数据——单个字节、几行文本。
  4. 操作系统送来整缓冲区的数据,java.io 的流数据类再花大量时间把它们拆成小块,往往拷贝一 个小块就要往返于几层对象。操作系统喜欢整卡车地运来数据,java.io 类则喜欢一铲子一铲子 地加工数据。

NIO

NIO可以轻松地把一卡车数据备份到您能直接使用的地方(ByteBuffer 对象)。

使用场景

如果代码大部分时间都处于 I/O 等待状态,那么,该考虑一下提升 I/O 效 率的问题了

I/O概念

1. 缓冲区操作

  • 输入/输出指的就是把数据移进或移出缓冲区
  • 进程执行I/O操作,就是向操作系统发出请求,让它要么把缓冲区里的数据排干(写),要么用数据把缓冲区填满 (读)。
图1

1.1 用户空间和内核空间

用户空间

  1. 用户空间是常规进程所在区域。JVM就是常规进程,驻守于用户空间。
  2. 用户空间是非特权区域,该区域执行的代码不能直接访问硬件设备。

内核空间

  1. 内核空间是操作系统所在区域。
  2. 内核代码有特别的权力,它能与设备控制器通讯,控制着用户区域进程的运行状态等
  3. 所有I/O 都直接或间接通过内核空间

1.2 I/O操作

  1. 当进程请求 I/O 操作的时候,它执行一个系统调用将控制权移交给内核。

C/C++程序员所熟知的底层函数 open( )、read( )、write( )和 close( )要做的无非就是建立和执行适当的系统调用。

当内核以这种方式被调用,它随即采取任何必要步骤,找到进程所需数据,并把数据 传送到用户空间内的指定缓冲区。内核试图对数据进行高速缓存或预读取,因此进程所需数据可能 已经在内核空间里了。如果是这样,该数据只需简单地拷贝出来即可。如果数据不在内核空间,则进程被挂起,内核着手把数据读进内存。

  1. 看了图 1,您可能会觉得,把数据从内核空间拷贝到用户空间似乎有些多余。为什么不直接 让磁盘控制器把数据送到用户空间的缓冲区呢?这样做有几个问题:

    • 首先,硬件通常不能直接访问 用户空间 。
    • 其次,像磁盘这样基于块存储的硬件设备操作的是固定大小的数据块,而用户进程请 求的可能是任意大小的或非对齐的数据块。
    • 在数据往来于用户空间与存储设备的过程中,内核负责数据的分解、再组合工作,因此充当着中间人的角色。
  2. 许多操作系统能把组装/分解过程进行得更加高效。

进程只需一个系统调用,就能把一连串缓冲区地址传递给操作系统。然后,内核就可以顺序填充或排干多个缓冲区,读的时候就把数据发散到多个用户空间缓冲区,写的时候再从多个缓冲区把数据汇聚起来

这样用户进程就不必多次执行系统调用(那样做可能代价不菲),内核也可以优化数据的处理 过程,因为它已掌握待传输数据的全部信息。

1.3 虚拟内存

所有现代操作系统都使用虚拟内存。虚拟内存意为使用虚假(或虚拟)地址取代物理(硬件 RAM)内存地址。

  1. 虚拟内存的好处
    • 一个以上的虚拟地址可指向同一个物理内存地址。
    • 虚拟内存空间可大于实际可用的硬件内存。
    • 把内核空间地址与用户空间的虚拟地址映射到同一个物理地址,这样, DMA 硬件(只能访问物理内存地址)就可以填充对内核与用户空间进程同时可见的缓冲区。
内存空间多重映射

1.4 文件I/O

文件系统是更高层次的抽象,是安排、解释磁盘(或其他随机存取块设备)数据的一种独特方 式。

文件系统把一连串大小一致的数据块组织到一起。有些块存储元信息,如空闲块、目录、索引 等的映射,有些包含文件数据。单个文件的元信息描述了哪些块包含文件数据、数据在哪里结束、 最后一次更新是什么时候,等等。

当用户进程请求读取文件数据时,文件系统需要确定数据具体在磁盘什么位置,然后着手把相 关磁盘扇区读进内存。 老式的操作系统往往直接向磁盘驱动器发布命令, 要求其读取所需磁盘扇 区。而采用分页技术的现代操作系统则利用请求页面调度取得所需数据。

1.4.1 内存映射文件

  1. 背景
    传统的文件 I/O 是通过用户进程发布 read( )和 write( )系统调用来传输数据的。为了在内核空间 的文件系统页与用户空间的内存区之间移动数据,一次以上的拷贝操作几乎总是免不了的。这是因 为,在文件系统页与用户缓冲区之间往往没有一一对应关系。

  2. 内存映射I/O

还有一种大多数操作系统都支 持的特殊类型的 I/O 操作,允许用户进程最大限度地利用面向页的系统 I/O 特性,并完全摒弃缓冲区拷贝。这就是内存映射 I/O

内存映射 I/O 使用文件系统建立从用户空间直到可用文件系统页的虚拟内存映射。

  1. 内存映射I/O的好处
    • 用户进程把文件数据当作内存,所以无需发布 read( )或 write( )系统调用。
    • 当用户进程碰触到映射内存空间,页错误会自动产生,从而将文件数据从磁盘读进内
      存。如果用户修改了映射内存空间,相关页会自动标记为脏,随后刷新到磁盘,文件得到更新。
    • 操作系统的虚拟内存子系统会对页进行智能高速缓存,自动根据系统负载进行内存管 理。
    • 数据总是按页对齐的,无需执行缓冲区拷贝。
    • 大型文件使用映射,无需耗费大量内存,即可进行数据拷贝。

虚拟内存和磁盘 I/O 是紧密关联的,从很多方面看来,它们只是同一件事物的两面。在处理大 量数据时,尤其要记得这一点。如果数据缓冲区是按页对齐的,且大小是内建页大小的倍数,那 么,对大多数操作系统而言,其处理效率会大幅提升。

1.4.2 文件锁定

文件锁定机制允许一个进程阻止其他进程存取某文件,或限制其存取方式。

通常的用途是控制 共享信息的更新方式,或用于事务隔离。在控制多个实体并行访问共同资源方面,文件锁定是必不可少的。数据库等复杂应用严重信赖于文件锁定。

“文件锁定”从字面上看有锁定整个文件的意思(通常的确是那样),但锁定往往可以发生在更 为细微的层面,锁定区域往往可以细致到单个字节。锁定与特定文件相关,开始于文件的某个特定 字节地址,包含特定数量的连续字节。这对于协调多个进程互不影响地访问文件不同区域,是至关 重要的。

  1. 文件锁定有两种方式
    • 共享的。 多个共享锁可同时对同一文件区域发生作用
    • 独占的。 独占锁它要求相关区域不能有其他锁定在起作用。
  2. 共享锁和独占锁的经典应用
    控制最初用于读取的共享文件的更新。某个进程要读取文件, 会先取得该文件或该文件部分区域的共享锁。第二个希望读取相同文件区域的进程也会请求共享锁。两个进程可以并行读取,互不影响。但是, 假如有第三个进程要更新该文件,它会请求独占 锁。该进程会处于阻滞状态,直到既有锁定(共享的、独占的)全部解除。一旦给予独占锁,其他 共享锁的读取进程会处于阻滞状态,直到独占锁解除。这样,更新进程可以更改文件,而其他读取 进程不会因为文件的更改得到前后不一致的结果。
共享锁阻断独占锁请求

独占锁阻断共享锁请求

1.5 流I/O

并非所有 I/O 都像前几节讲的是面向块的,也有流 I/O,其原理模仿了通道。I/O 字节流必须顺序存取,常见的例子有 TTY(控制台)设备、打印机端口和网络连接。

流的传输一般(也不必然如此)比块设备慢,经常用于间歇性输入。多数操作系统允许把流置 于非块模式,这样,进程可以查看流上是否有输入,即便当时没有也不影响它干别的。这样一种能 力使得进程可以在有输入的时候进行处理,输入流闲置的时候执行其他功能。

比非块模式再进一步,就是就绪性选择。就绪性选择与非块模式类似(常常就是建立在非块模 式之上),但是把查看流是否就绪的任务交给了操作系统。操作系统受命查看一系列流,并提醒进 程哪些流已经就绪。这样,仅仅凭借操作系统返回的就绪信息,进程就可以使用相同代码和单一线 程,实现多活动流的多路传输。这一技术广泛用于网络服务器领域,用来处理数量庞大的网络连 接。就绪性选择在大容量缩放方面是必不可少的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354

推荐阅读更多精彩内容