Java I/O,NIO,BIO,AIO,AutoCloseable/Closeable/Flushable,IO优化

Java IO流学习总结- http://geek.csdn.net/news/detail/236481

LinkedBlockingQueue的put,add跟offer的区别- https://blog.csdn.net/z69183787/article/details/46986823
ByteBuffer的Put和Get的用法和要注意的细节- https://blog.csdn.net/liuguangqiang/article/details/52128076
ByteBuffer常用方法详解- http://1028826685.iteye.com/blog/2330760
图解ByteBuffer- https://www.cnblogs.com/ruber/p/6857159.html

-- Java NIO工作机制简介- https://blog.csdn.net/u014427391/article/details/79855294

  I/O 以流的方式处理数据,而 NIO 以缓冲区的方式处理数据;IO是阻塞的,NIO是非阻塞的,直到有数据被读取或者数据完全写入时,IO线程才开始执行操作,而NIO在如何情况都是非阻塞的
  NIO三个核心对象:通道(Channel)、缓冲区(Buffer)和选择器(Selector)。
  缓冲区只暂时储存数据,通道用于读取和写入操作,作用相当于IO流,与IO流不同的是通道是双向的。
  NIO操作中,从通道读取的数据必须先放在缓冲区中,发送给通道的数据也先放在缓冲区中。
  通道和流的区别在于通道是双向。通道可以用于读、写或者同时用于读写,而流只有一个方向,即一个流必须是InputStream的子类或者OutputStream的子类。

-- 按I/O类型来总体分类:

1. Memory 1)从/向内存数组读写数据: CharArrayReader、 CharArrayWriter、ByteArrayInputStream、ByteArrayOutputStream
          2)从/向内存字符串读写数据 StringReader、StringWriter、StringBufferInputStream
2.Pipe管道  实现管道的输入和输出(进程间通信): PipedReader、PipedWriter、PipedInputStream、PipedOutputStream
3.File 文件流。对文件进行读、写操作 :FileReader、FileWriter、FileInputStream、FileOutputStream
4.ObjectSerialization 对象输入、输出 :ObjectInputStream、ObjectOutputStream
5.DataConversion数据流 按基本数据类型读、写(处理的数据是Java的基本类型(如布尔型,字节,整数和浮点数)):  DataInputStream、DataOutputStream
6.Printing 包含方便的打印方法 :PrintWriter、PrintStream
7.Buffering缓冲  在读入或写出时,对数据进行缓存,以减少I/O的次数:BufferedReader、BufferedWriter、    BufferedInputStream、BufferedOutputStream
8.Filtering 滤流,在数据进行读或写时进行过滤:FilterReader、FilterWriter、FilterInputStream、FilterOutputStream过
9.Concatenation合并输入 把多个输入流连接成一个输入流 :SequenceInputStream 
10.Counting计数  在读入数据时对行记数 :LineNumberReader、LineNumberInputStream
11.Peeking Ahead 通过缓存机制,进行预读 :PushbackReader、PushbackInputStream

12.Converting between Bytes and Characters 按照一定的编码/解码标准将字节流转换为字符流,或进行反向转换(Stream到Reader,Writer的转换类):InputStreamReader、OutputStreamWriter

-- 对象输入输出流ObjectInputStream、ObjectOutputStream(对象序列化与反序列化): 
ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream("文件路径"));
 oo.writeObject(对象);  //来将对象的内容写到指定路径

ObjectInputStream oi = new ObjectInputStream(new FileInputStream("文件路径"));
 类名 对象名 = (对象名) oi.readObject(); //来将指定路径的内容读入对象中

-- JAVA字节流与字符流

 JAVA字节流:FileInputStream和FileOutputStream;BufferedInputStream和BufferedOutputStream;DataInputStream和DataOutputStream;
 Java的字符流:InputStreamReader和OutputStreamWriter
 Java有一种特殊类型的IO数据流:DataOutputStream

> Java IO NIO
  NIO即New IO,这个库是在JDK1.4中才引入的。在Java API中提供了两套NIO,一套是针对标准输入输出NIO,另一套就是网络编程NIO。
    IO:面向流,阻塞IO,无;
    NIO:面向缓冲,非阻塞IO,选择器。
   Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。
    I- 就是从硬盘到内存; O- 就是从内存到硬盘。

> BIO/ NIO/ AIO
  IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。
 NIO本身是基于事件驱动思想来完成的,其主要想解决的是BIO的大并发问题: 在使用同步I/O的网络应用中,如果要同时处理多个客户端请求,或是在客户端要同时和多个服务器进行通讯,就必须使用多线程来处理。
 BIO与NIO一个比较重要的不同,是我们使用BIO的时候往往会引入多线程,每个连接一个单独的线程;而NIO则是使用单线程或者只使用少量的多线程,每个连接共用一个线程。

AIO:AsynchronousSocketChannel;AsynchronousServerSocketChannel;

AsynchronousFileChannel;AsynchronousDatagramChannel
 

> Java对BIO、NIO、AIO的支持:
  Java BIO : 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
  Java NIO : 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
  Java AIO(NIO.2) : 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理,
> BIO、NIO、AIO适用场景分析:
  BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。
  NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
  AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。
  另外,I/O属于底层操作,需要操作系统支持,并发也需要操作系统的支持,所以性能方面不同操作系统差异会比较明显。
  在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作。

  什么是阻塞和非阻塞,什么是同步和异步,同步和异步是针对应用程序和内核的交互而言的,同步指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪,而异步是指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO完成的通知。

一般来说I/O模型可以分为:同步阻塞,同步非阻塞,异步阻塞,异步非阻塞IO
  同步阻塞IO:在此种方式下,用户进程在发起一个IO操作以后,必须等待IO操作的完成,只有当真正完成了IO操作以后,用户进程才能运行。JAVA传统的IO模型属于此种方式!
  同步非阻塞IO:在此种方式下,用户进程发起一个IO操作以后边可返回做其它事情,但是用户进程需要时不时的询问IO操作是否就绪,这就要求用户进程不停的去询问,从而引入不必要的CPU资源浪费。其中目前JAVA的NIO就属于同步非阻塞IO。
  异步阻塞IO:此种方式下是指应用发起一个IO操作以后,不等待内核IO操作的完成,等内核完成IO操作以后会通知应用程序,这其实就是同步和异步最关键的区别,同步必须等待或者主动的去询问IO是否完成,那么为什么说是阻塞的呢?因为此时是通过select系统调用来完成的,而select函数本身的实现方式是阻塞的,而采用select函数有个好处就是它可以同时监听多个文件句柄,从而提高系统的并发性!
  异步非阻塞IO:在此种模式下,用户进程只需要发起一个IO操作然后立即返回,等IO操作真正的完成以后,应用程序会得到IO操作完成的通知,此时用户进程只需要对数据进行处理就好了,不需要进行实际的IO读写操作,因为真正的IO读取或者写入操作已经由内核完成了。目前Java中还没有支持此种IO模型。   

-- 简单说下每种模型的典型应用,你可能会对应用场景有所了解了。
BIO:Apache,Tomcat。主要是并发量要求不高的场景
NIO:Nginx,Netty。主要是高并发量要求的场景
AIO:还不是特别成熟,底层也基本是多线程模拟,所以应用场景不多,Netty曾经用了,但又放弃了。

BIO,同步阻塞式IO,简单理解:一个连接一个线程
NIO,同步非阻塞IO,简单理解:一个请求一个线程
AIO,异步非阻塞IO,简单理解:一个有效请求一个线程

另外,I/O属于底层操作,需要操作系统支持,并发也需要操作系统的支持,所以性能方面不同操作系统差异会比较明显。

-- java IO之AutoCloseable,Closeable和Flushable接口- https://www.cnblogs.com/demacian/p/4511488.html
  有3个接口对于流类相当重要。
  它们是在java.io包中定义的,并且是由JDK5添加的,Closeable和Flushable;写入流的所有I/O类都实现了Flushable接口。
  第3个接口是AutoColseable,它是由JDK7添加的新接口,被打包到java.lang包中;在JDK7中,所有实现了Closeable接口的类也都实现了AutoCloseable接口。
  AutoCloseable接口对JDK7新添加的带资源的try语句提供了支持,这种try语句可以自动执行资源关闭过程。只有实现了AutoCloseable接口的类的对象才可以由带资源的try语句进行管理。AutoCloseable接口只定义了close()方法:

> IO 优化和内存分析
Java I/O 操作及优化建议- http://www.importnew.com/16481.html
  Java I/O,I/O,即 Input/Output(输入/输出) 的简称。就 I/O 而言,概念上有 5 种模型:blocking I/O,nonblocking I/O,I/O multiplexing (select and poll),signal driven I/O (SIGIO),asynchronous I/O (the POSIX aio_functions)。不同的操作系统对上述模型支持不同,UNIX 支持 IO 多路复用。不同系统叫法不同,freebsd 里面叫 kqueue,Linux 叫 epoll。而 Windows2000 的时候就诞生了 IOCP 用以支持 asynchronous I/O。

  Java NIO,Java.nio 包是 Java 在 1.4 版本之后新增加的包,专门用来提高 I/O 操作的效率。
  一旦读完了所有的数据,就需要清空缓冲区,让它可以再次被写入。有两种方式能清空缓冲区:调用 clear() 或 compact() 方法。clear() 方法会清空整个缓冲区。compact() 方法只会清除已经读过的数据。任何未读的数据都被移到缓冲区的起始处,新写入的数据将放到缓冲区未读数据的后面。

  传统 I/O、基于 Byte 的 NIO、基于内存映射的 NIO 三种方式。I/O 包括磁盘 I/O 和网络 I/O。

Java中的流,可以从不同的角度进行分类:
按照数据流的方向不同可以分为:输入流和输出流。
按照处理数据单位不同可以分为:字节流和字符流。
按照实现功能不同可以分为:节点流和处理流。

 字节流:一次读入或读出是8位二进制。 字符流:一次读入或读出是16位二进制。
 字节流和字符流的原理是相同的,只不过处理的单位不同而已。后缀是Stream是字节流,而后缀是Reader,Writer是字符流。
 Jdk提供的流继承了四大类:InputStream(字节输入流),OutputStream(字节输出流),Reader(字符输入流),Writer(字符输出流)。
  使用字节流好还是字符流好呢?答案是字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。但是字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。
  数据持久化或网络传输都是以字节进行的,所以必须要有字符到字节或字节到字符的转化。

  InputStreamReader 类是字节到字符的转化桥梁,InputStream 到 Reader 的过程要指定编码字符集,否则将采用操作系统默认字符集,很可能会出现乱码问题。StreamDecoder 正是完成字节到字符的解码的实现类。

  对文件进行操作:FileInputStream(字节输入流),FileOutputStream(字节输出流),FileReader(字符输入流),FileWriter(字符输出流)
  对管道进行操作:PipedInputStream(字节输入流),PipedOutStream(字节输出流),PipedReader(字符输入流),PipedWriter(字符输出流)。

网络 I/O 优化通常有一些基本处理原则:
 1.一个是减少网络交互的次数:要减少网络交互的次数通常我们在需要网络交互的两端会设置缓存,比如 Oracle 的 JDBC 驱动程序,就提供了对查询的 SQL 结果的缓存,在客户端和数据库端都有,可以有效的减少对数据库的访问。关于 Oracle JDBC 的内存管理可以参考《 Oracle JDBC 内存管理》。除了设置缓存还有一个办法是,合并访问请求:如在查询数据库时,我们要查 10 个 id,我可以每次查一个 id,也可以一次查 10 个 id。再比如在访问一个页面时通过会有多个 js 或 css 的文件,我们可以将多个 js 文件合并在一个 HTTP 链接中,每个文件用逗号隔开,然后发送到后端 Web 服务器根据这个 URL 链接,再拆分出各个文件,然后打包再一并发回给前端浏览器。这些都是常用的减少网络 I/O 的办法。
 2.减少网络传输数据量的大小:减少网络数据量的办法通常是将数据压缩后再传输,如 HTTP 请求中,通常 Web 服务器将请求的 Web 页面 gzip 压缩后在传输给浏览器。还有就是通过设计简单的协议,尽量通过读取协议头来获取有用的价值信息。比如在代理程序设计时,有 4 层代理和 7 层代理都是来尽量避免要读取整个通信数据来取得需要的信息。
 3.尽量减少编码:通常在网络 I/O 中数据传输都是以字节形式的,也就是通常要序列化。但是我们发送要传输的数据都是字符形式的,从字符到字节必须编码。但是这个编码过程是比较耗时的,所以在要经过网络 I/O 传输时,尽量直接以字节形式发送。也就是尽量提前将字符转化为字节,或者减少字符到字节的转化过程。
 4.根据应用场景设计合适的交互方式:所谓的交互场景主要包括同步与异步阻塞与非阻塞方式

Java IO流分析、IO整理与IO优化- https://blog.csdn.net/huilaojia123/article/details/24637413
几种常见的编码格式- https://www.ibm.com/developerworks/cn/java/j-lo-chinesecoding/

Charset 提供 encode 与 decode 分别对应 char[] 到 byte[] 的编码和 byte[] 到 char[] 的解码。
Charset charset = Charset.forName("UTF-8"); 
ByteBuffer byteBuffer = charset.encode(string); 
CharBuffer charBuffer = charset.decode(byteBuffer);

对于调优这个事情来说,一般就是三个过程:
 1.性能监控:问题没有发生,你并不知道你需要调优什么?此时需要一些系统、应用的监控工具来发现问题。
 2.性能分析:问题已经发生,但是你并不知道问题到底出在哪里。此时就需要使用工具、经验对系统、应用进行瓶颈分析,以求定位到问题原因。
 3.性能调优:经过上一步的分析定位到了问题所在,需要对问题进行解决,使用代码、配置等手段进行优化。

系统层面能够影响应用性能的一般包括三个因素:CPU、内存和IO。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值