- 浏览: 957380 次
- 性别:
- 来自: 江西上饶
文章分类
- 全部博客 (460)
- p.spring (56)
- p.maven (20)
- p.ant (17)
- p.jee (18)
- p.jse (33)
- p.ofbiz (31)
- p.软件工程 (8)
- p.struts2 (5)
- p.hibernate (5)
- linux (25)
- 设计模式 (2)
- p.javascript (11)
- 硬件 (1)
- p.jsp (2)
- p.windows批处理 (1)
- 操作系统问题 (5)
- 算法 (1)
- p.mysql (7)
- p.sql (5)
- p.c (1)
- google产品 (0)
- 内存 (1)
- p.struts (1)
- p.freemarker (7)
- p.css (4)
- p.log4j (10)
- p.html (3)
- 淘宝产品 (0)
- 其他 (3)
- 编译器 (0)
- svn (4)
- p.spring.security (11)
- 图形 (0)
- p.xml (1)
- p.ssh (0)
- p.jquery (4)
- p.jdbc (3)
- p.flex (0)
- p.c++ (0)
- p.c#Net (0)
- p.assembly (0)
- p.sqlserver (0)
- p.其他 (3)
- p.webwork (21)
- p.wap (12)
- p.cglib (1)
- p.jee服务器 (11)
- windows (2)
- p.iphone (1)
- p.java.分布式与集群 (2)
- p.ibatis (16)
- p.eclipse (5)
- 架构 (2)
- http协议 (5)
- 我的个人标准 (2)
- 多线程 (1)
- 奇怪问题 (5)
- p.jira (13)
- p.httpclient (1)
- 服务器.apache (11)
- 安全防范 (1)
- p.PODAM (1)
- p.junit (16)
- fop (2)
- 硬盘安装 (1)
- powerdesigner (0)
- 单元测试 (1)
- apache commons (4)
- tomcat+apache集群 (10)
- 各类诡辩 (1)
- 安卓 (8)
- qvod (1)
- java编程基础知识考试考点及答案 (0)
- 工作总结 (4)
- oracle (0)
- spring的util工具 (3)
- json (2)
- maven (3)
- jms (19)
- p.bat (3)
- hadoop (2)
- git (3)
- nginx (1)
- p.移动开发 (1)
- shiro (3)
- 游戏破解 (1)
- react-native (7)
- ios开发 (1)
- webmagic (6)
- socks5 (1)
最新评论
-
weituotian:
说的不好,没人看的
公司系统中的菜单功能和权限功能 -
石不易:
非常详细的注解~
绑定端口和IP,Listen 与VirtualHost指令 -
spring_springmvc:
spring mvc demo教程源代码下载,地址:http: ...
spring mvc -
liyixing1:
PandaDONG 写道谢谢你啊,我已经下下来了,只是还有很多 ...
jira war安装 -
liyixing1:
PandaDONG 写道谢谢你啊,我已经下下来了,只是还有很多 ...
jira war安装
几个概念:
缓冲区(Buffers)
新的 Buffer 类是常规 Java 类和通道之间的纽带。原始数据元素组成的固定长度数组,封装在
包含状态信息的对象中,存入缓冲区。缓冲区提供了一个会合点:通道既可提取放在缓冲区中的数
据(写),也可向缓冲区存入数据供读取(读)。此外,还有一种特殊类型的缓冲区,用于内存映
射文件。
通道(Channels)
NIO 新引入的最重要的抽象是通道的概念。Channel 对象模拟了通信连接,管道既可以是单向
的(进或出),也可以是双向的(进和出)。可以把通道想象成连接缓冲区和 I/O 服务的捷径
文件锁定和内存映射文件(File locking and memory-mapped files)
新的 FileChannel 对象包含在 java.nio.channels 软件包内,提供许多面向文件的新特
性,其中最有趣的两个是文件锁定和内存映射文件。
在多个进程协同工作的情况下,要协调各个进程对共享数据的访问,文件锁定是必不可少的工
具。
将文件映射到内存,这样在您看来,磁盘上的文件数据就像是在内存中一样。这利用了操作系
统的虚拟内存功能,无需在内存中实际保留一份文件的拷贝,就可实现文件内容的动态高速缓存。
套接字(Sockets)
套接字通道类为使用网络套接字实现交互提供了新方法。套接字通道可工作于非块模式,并可
与选择器一同使用。因此,多个套接字可实现多路传输,管理效率也比 java.net 提供的传统套
接字更高。
三个新套接字通道,即 ServerSocketChannel、SocketChannel 和 DatagramChannel
选择器(Selectors)
选择器可实现就绪性选择。Selector 类提供了确定一或多个通道当前状态的机制。使用选择
器,借助单一线程,就可对数量庞大的活动 I/O 通道实施监控和维护。
正则表达式(Regular expressions)
新增的 java.util.regex 软件包将类似 Perl 语言的正则表达式处理机制引入 Java。这一人
们期盼已久的特性有着广泛用途。
新的正则表达式 API 之所以被看成是 NIO 的组成部分,是因 JSR 51 把它与其他 NIO 特性放在
一起作了详细说明。虽然它在许多方面与 NIO 的其他组成部分缺乏平行关系,但它在文件处理等
众多领域都是极其有用的。
字符集(Character sets)
java.nio.charsets 提供了新类用于处理字符与字节流之间的映射关系。您可以对字符转
5
换映射方式进行选择,也可以自己创建映射。
磁盘I/O的示例
图中明显忽略了很多细节,仅显示了涉及到的基本步骤。
如图
注意图中用户空间和内核空间的概念。用户空间是常规进程所在区域。JVM 就是常规进程,
驻守于用户空间。用户空间是非特权区域:比如,在该区域执行的代码就不能直接访问硬件设备。
内核空间是操作系统所在区域。内核代码有特别的权力:它能与设备控制器通讯,控制着用户区域
进程的运行状态,等等。最重要的是,所有 I/O 都直接(如这里所述)或间接(见 1.4.2 小节)通
过内核空间。
当进程请求 I/O 操作的时候,它执行一个系统调用(有时称为陷阱)将控制权移交给内核。
C/C++程序员所熟知的底层函数 open( )、read( )、write( )和 close( )要做的无非就是建立和执行适当
的系统调用。当内核以这种方式被调用,它随即采取任何必要步骤,找到进程所需数据,并把数据
传送到用户空间内的指定缓冲区。内核试图对数据进行高速缓存或预读取,因此进程所需数据可能
已经在内核空间里了。如果是这样,该数据只需简单地拷贝出来即可。如果数据不在内核空间,则
进程被挂起,内核着手把数据读进内存。
看了图 1-1,您可能会觉得,把数据从内核空间拷贝到用户空间似乎有些多余。为什么不直接
让磁盘控制器把数据送到用户空间的缓冲区呢?这样做有几个问题。首先,硬件通常不能直接访问
用户空间 1。其次,像磁盘这样基于块存储的硬件设备操作的是固定大小的数据块,而用户进程请
求的可能是任意大小的或非对齐的数据块。在数据往来于用户空间与存储设备的过程中,内核负责
数据的分解、再组合工作,因此充当着中间人的角色。
发散/汇聚
许多操作系统能把组装/分解过程进行得更加高效。根据发散/汇聚的概念,进程只需一个系
统调用,就能把一连串缓冲区地址传递给操作系统。然后,内核就可以顺序填充或排干多个缓冲
区,读的时候就把数据发散到多个用户空间缓冲区,写的时候再从多个缓冲区把数据汇聚起来
这样用户进程就不必多次执行系统调用(那样做可能代价不菲),内核也可以优化数据的处理
过程,因为它已掌握待传输数据的全部信息。如果系统配有多个 CPU,甚至可以同时填充或排干
多个缓冲区。
虚拟内存
所有现代操作系统都使用虚拟内存。虚拟内存意为使用虚假(或虚拟)地址取代物理(硬件
RAM)内存地址。这样做好处颇多,总结起来可分为两大类:
1. 一个以上的虚拟地址可指向同一个物理内存地址。
2. 虚拟内存空间可大于实际可用的硬件内存。
设备控制器不能通过 DMA 直接存储到用户空间,但通过利用上面提到的第一
项,则可以达到相同效果。把内核空间地址与用户空间的虚拟地址映射到同一个物理地址,这样,
DMA 硬件(只能访问物理内存地址)就可以填充对内核与用户空间进程同时可见的缓冲区
如图,进程虚拟内存和内核虚拟内存映射到的物理地址都一样,这样DMA写到实际的物理内存后,两个缓冲区指向的物理地址都一样,那么他们就同时能访问到数据了。
但前提条件是,内核与用户缓冲区必须
使用相同的页对齐,缓冲区的大小还必须是磁盘控制器块大小(通常为 512 字节磁盘扇区)的倍
数。操作系统把内存地址空间划分为页,即固定大小的字节组。内存页的大小总是磁盘块大小的倍
数,通常为 2 次幂(这样可简化寻址操作)。典型的内存页为 1,024、2,048 和 4,096 字节。虚拟和
物理内存页的大小总是相同的。
如上图显示了来自多个虚拟地址的虚拟内存页是如何映射到物理内
内存页面调度
为了支持虚拟内存的第二个特性(寻址空间大于物理内存),就必须进行虚拟内存分页(经常
称为交换,虽然真正的交换是在进程层面完成,而非页层面)。依照该方案,虚拟内存空间的页面
能够继续存在于外部磁盘存储,这样就为物理内存中的其他虚拟页面腾出了空间。从本质上说,物
理内存充当了分页区的高速缓存;而所谓分页区,即从物理内存置换出来,转而存储于磁盘上的内
存页面。
缓冲区(Buffers)
新的 Buffer 类是常规 Java 类和通道之间的纽带。原始数据元素组成的固定长度数组,封装在
包含状态信息的对象中,存入缓冲区。缓冲区提供了一个会合点:通道既可提取放在缓冲区中的数
据(写),也可向缓冲区存入数据供读取(读)。此外,还有一种特殊类型的缓冲区,用于内存映
射文件。
通道(Channels)
NIO 新引入的最重要的抽象是通道的概念。Channel 对象模拟了通信连接,管道既可以是单向
的(进或出),也可以是双向的(进和出)。可以把通道想象成连接缓冲区和 I/O 服务的捷径
文件锁定和内存映射文件(File locking and memory-mapped files)
新的 FileChannel 对象包含在 java.nio.channels 软件包内,提供许多面向文件的新特
性,其中最有趣的两个是文件锁定和内存映射文件。
在多个进程协同工作的情况下,要协调各个进程对共享数据的访问,文件锁定是必不可少的工
具。
将文件映射到内存,这样在您看来,磁盘上的文件数据就像是在内存中一样。这利用了操作系
统的虚拟内存功能,无需在内存中实际保留一份文件的拷贝,就可实现文件内容的动态高速缓存。
套接字(Sockets)
套接字通道类为使用网络套接字实现交互提供了新方法。套接字通道可工作于非块模式,并可
与选择器一同使用。因此,多个套接字可实现多路传输,管理效率也比 java.net 提供的传统套
接字更高。
三个新套接字通道,即 ServerSocketChannel、SocketChannel 和 DatagramChannel
选择器(Selectors)
选择器可实现就绪性选择。Selector 类提供了确定一或多个通道当前状态的机制。使用选择
器,借助单一线程,就可对数量庞大的活动 I/O 通道实施监控和维护。
正则表达式(Regular expressions)
新增的 java.util.regex 软件包将类似 Perl 语言的正则表达式处理机制引入 Java。这一人
们期盼已久的特性有着广泛用途。
新的正则表达式 API 之所以被看成是 NIO 的组成部分,是因 JSR 51 把它与其他 NIO 特性放在
一起作了详细说明。虽然它在许多方面与 NIO 的其他组成部分缺乏平行关系,但它在文件处理等
众多领域都是极其有用的。
字符集(Character sets)
java.nio.charsets 提供了新类用于处理字符与字节流之间的映射关系。您可以对字符转
5
换映射方式进行选择,也可以自己创建映射。
磁盘I/O的示例
图中明显忽略了很多细节,仅显示了涉及到的基本步骤。
如图
注意图中用户空间和内核空间的概念。用户空间是常规进程所在区域。JVM 就是常规进程,
驻守于用户空间。用户空间是非特权区域:比如,在该区域执行的代码就不能直接访问硬件设备。
内核空间是操作系统所在区域。内核代码有特别的权力:它能与设备控制器通讯,控制着用户区域
进程的运行状态,等等。最重要的是,所有 I/O 都直接(如这里所述)或间接(见 1.4.2 小节)通
过内核空间。
当进程请求 I/O 操作的时候,它执行一个系统调用(有时称为陷阱)将控制权移交给内核。
C/C++程序员所熟知的底层函数 open( )、read( )、write( )和 close( )要做的无非就是建立和执行适当
的系统调用。当内核以这种方式被调用,它随即采取任何必要步骤,找到进程所需数据,并把数据
传送到用户空间内的指定缓冲区。内核试图对数据进行高速缓存或预读取,因此进程所需数据可能
已经在内核空间里了。如果是这样,该数据只需简单地拷贝出来即可。如果数据不在内核空间,则
进程被挂起,内核着手把数据读进内存。
看了图 1-1,您可能会觉得,把数据从内核空间拷贝到用户空间似乎有些多余。为什么不直接
让磁盘控制器把数据送到用户空间的缓冲区呢?这样做有几个问题。首先,硬件通常不能直接访问
用户空间 1。其次,像磁盘这样基于块存储的硬件设备操作的是固定大小的数据块,而用户进程请
求的可能是任意大小的或非对齐的数据块。在数据往来于用户空间与存储设备的过程中,内核负责
数据的分解、再组合工作,因此充当着中间人的角色。
发散/汇聚
许多操作系统能把组装/分解过程进行得更加高效。根据发散/汇聚的概念,进程只需一个系
统调用,就能把一连串缓冲区地址传递给操作系统。然后,内核就可以顺序填充或排干多个缓冲
区,读的时候就把数据发散到多个用户空间缓冲区,写的时候再从多个缓冲区把数据汇聚起来
这样用户进程就不必多次执行系统调用(那样做可能代价不菲),内核也可以优化数据的处理
过程,因为它已掌握待传输数据的全部信息。如果系统配有多个 CPU,甚至可以同时填充或排干
多个缓冲区。
虚拟内存
所有现代操作系统都使用虚拟内存。虚拟内存意为使用虚假(或虚拟)地址取代物理(硬件
RAM)内存地址。这样做好处颇多,总结起来可分为两大类:
1. 一个以上的虚拟地址可指向同一个物理内存地址。
2. 虚拟内存空间可大于实际可用的硬件内存。
设备控制器不能通过 DMA 直接存储到用户空间,但通过利用上面提到的第一
项,则可以达到相同效果。把内核空间地址与用户空间的虚拟地址映射到同一个物理地址,这样,
DMA 硬件(只能访问物理内存地址)就可以填充对内核与用户空间进程同时可见的缓冲区
如图,进程虚拟内存和内核虚拟内存映射到的物理地址都一样,这样DMA写到实际的物理内存后,两个缓冲区指向的物理地址都一样,那么他们就同时能访问到数据了。
但前提条件是,内核与用户缓冲区必须
使用相同的页对齐,缓冲区的大小还必须是磁盘控制器块大小(通常为 512 字节磁盘扇区)的倍
数。操作系统把内存地址空间划分为页,即固定大小的字节组。内存页的大小总是磁盘块大小的倍
数,通常为 2 次幂(这样可简化寻址操作)。典型的内存页为 1,024、2,048 和 4,096 字节。虚拟和
物理内存页的大小总是相同的。
如上图显示了来自多个虚拟地址的虚拟内存页是如何映射到物理内
内存页面调度
为了支持虚拟内存的第二个特性(寻址空间大于物理内存),就必须进行虚拟内存分页(经常
称为交换,虽然真正的交换是在进程层面完成,而非页层面)。依照该方案,虚拟内存空间的页面
能够继续存在于外部磁盘存储,这样就为物理内存中的其他虚拟页面腾出了空间。从本质上说,物
理内存充当了分页区的高速缓存;而所谓分页区,即从物理内存置换出来,转而存储于磁盘上的内
存页面。
发表评论
-
java实现socks5
2019-07-16 23:05 1714socks5的基础知识 关于socks5的定义]https: ... -
java Runtime.exec方法详解
2019-07-11 14:11 21431.关于CMD(为了让exec ... -
Spring 定时任务,cron表达式,@Scheduled cron表达式
2016-04-25 15:48 5296一个cron表达式有至少6 ... -
xulrunner
2016-01-13 13:07 663http://ftp.mozilla.org/pub/xulr ... -
谈一谈自己对依赖、关联、聚合和组合之间区别的理解
2015-11-17 16:05 775在学习面向对象设计对象关系时,依赖、关联、聚合和组合这四种关系 ... -
java apache common unicode处理
2015-09-19 15:17 1557if (UnicodeConvertType.中文转unico ... -
jdbc ssh通道
2015-09-17 14:40 1853java通过ssh链接数据库,需要用到 JSCH是一个纯粹的用 ... -
swt 窗口 最大化最小化按钮设置等
2015-09-14 17:53 4304窗体顶部菜可以在实例化的时候设置,也可以单独设置:Shell ... -
java.lang.Process调用程序阻塞问题解决
2015-08-14 10:56 4252这两天一直在处理flv视频环境的搭建工作,包括服务器的安 ... -
java html解析
2015-07-31 17:31 1201dom解析是常用dom4j。 android中我们常用的是sa ... -
slf4j门面模式实现原理
2015-07-16 10:08 2978在使用slf4j的时候,只 ... -
java - 比较时间-相差月数
2015-06-15 09:57 1454Date经常会出现比较两个Date相差的月数,实际上可以做一个 ... -
log4jdbc
2014-12-25 13:55 3044该框架目前支持到jdbc3.和jdbc4的版本。 提供了多种 ... -
jdbc规范 jdbc1 jdbc2 jdbc3 jdbc4
2014-12-25 13:49 5048目前jdbc规范已经升级到 ... -
反射,代理,动态java原理
2014-12-22 16:44 1114需要两个类,用于下面的测试 package test; ... -
Bean Validation 1.0(JSR-303)
2014-11-18 16:15 1087http://jinnianshilongnian.iteye ... -
JRE最小化原理
2014-10-15 20:19 1299比如我们一个程序只用到了很少的类,像String,Intege ... -
时间重叠的判断
2014-02-14 11:16 1645如上图,粗线是时间1 细线是时间2 时间重叠,只可能是以上四 ... -
java获取当前类的绝对路径
2013-12-14 00:37 8951.如何获得当前文件路径 常用: (1).Test.class ... -
枚举 enum
2013-12-13 16:52 5226java的enum其实是一个类。编译器根据你enum的定义会为 ...
相关推荐
对于NIO的学习和开发,一些工具可以提供帮助: 1. **IDEA插件**:某些IDEA插件,如`JProfiler`,可以显示NIO操作的性能指标,帮助优化代码。 2. **网络抓包工具**:如`Wireshark`,可以观察网络I/O的实际数据传输...
**NIO(New Input/Output)是Java编程语言中用于替代标准I/O(BIO,Blocking I/O)的一组API,它提供了非阻塞式的I/O...了解并掌握NIO的这些核心概念和技术,对于提升Java应用的性能和设计高质量的系统架构至关重要。
- **关键特性**:NIO 支持缓冲区(Buffer)、通道(Channel)等核心概念,以及异步 I/O 和直接缓冲区等特性,这些都是原始 I/O 包无法提供的功能。 #### 二、NIO 的基础概念 - **缓冲区(Buffer)**:缓冲区是 NIO 中的...
**NIO(Non-blocking Input/Output)**是Java在1.4版本引入的一种新的I/O模型,它提供了与...然而,NIO的学习曲线相对较陡峭,需要对操作系统级别的I/O模型有一定了解,但一旦掌握,将极大地提升系统的性能和可扩展性。
### Java NIO 系列教程(一):Java NIO 概述 ...通过本文的学习,相信您已经对Java NIO的核心概念有了初步的了解。在未来的学习过程中,继续深入理解这些概念将有助于您更好地掌握Java NIO技术。
这意味着开发者需要了解何时使用新 API,何时使用旧版 API。本书也会对此进行详细解释,帮助开发者根据特定应用场景选择最适合的方案。 ### Java NIO 的主要概念 #### 1. Buffer(缓冲区) - **Buffer 基础**:...
本项目源码包含了NIO相关的实现,通过分析这些代码,我们可以深入了解NIO的工作原理和实际应用。 1. NIO基础概念 - Channel(通道):NIO的核心组件,它代表了数据传输的路径,如文件、套接字等。通道是双向的,...
本示例"JAVA-NIO-DEMO"提供了关于Java NIO的实际应用,通过Anontion(注解)、Applet(小程序)和NIO的Demo,帮助开发者更深入地理解和掌握这些概念。 首先,让我们深入了解Java NIO。NIO的核心组件包括: 1. **...
解决这些问题通常需要深入理解NIO的工作原理,包括缓冲区(Buffer)、通道(Channel)、选择器(Selector)等核心概念,并且需要对Servlet容器的内部机制有一定的了解。 在提供的文件列表中,"src"目录可能包含了源...
在Java NIO中,主要有以下核心概念: 1. **通道(Channels)**:通道类似于流,但它们是双向的,可以读取和写入数据。常见的通道有FileChannel、SocketChannel、ServerSocketChannel等。 2. **缓冲区(Buffer)**:在...
通过这个实例,开发者可以学习如何设置NIO服务器,如何处理多个并发连接,并了解NIO如何提高服务器的吞吐量和响应性。NIO适用于需要处理大量并发连接的场景,例如聊天服务器、游戏服务器等。理解并掌握Java NIO的...
本实用教程从高级概念到底层的编程细节,非常详细地介绍了 NIO 库。您将学到诸如缓冲区和通道这样的关键 I/O 元素的知识,并考察更新后的库中的标准 I/O 是如何工作的。您还将了解只能通过 NIO 来完成的工作,如异步...
通过阅读给定的博文链接(虽然此处链接无法访问),我们可以深入了解Java NIO的具体用法和最佳实践,以及在实际项目中如何利用NIO优化性能。学习和掌握NIO技术对于任何Java开发者来说都是非常有价值的,特别是那些...