• BIO、NIO、AIO


    I/O是机器获取和交换信息的主要渠道,而流是完成I/O操作的主要方式。

    流分为输入流(InputStream)和输出流(OutputStream)。

    在Java的I/O操作类的包下,InputStream,OutputStream以及Reader和Writer类是I/O包中的4个基本类,分别用来处理字节流和字符流。

    字节是文件的最小存储单元,为什么还会出现字符流呢?因为我们在字节到字符的时候必须经过转码,这是一个耗时的过程,所以Java直接提供了一个字符流的操作接口。

    BIO

    传统的IO模型是同步阻塞IO,也称为BIO,所谓同步阻塞,就是指在程序在执行IO过程中,需要等待IO的操作完成,这期间线程处于阻塞状态,不能去处理别的事情。

    在传统 I/O 中,InputStream 的 read() 是一个 while 循环操作,它会一直等待数据读取,直到数据就绪才会返回。这就意味着如果没有数据就绪,这个读取操作将会一直被挂起,用户线程将会处于阻塞状态。在少量连接请求的情况下,使用这种方式没有问题,响应速度也很高。但在发生大量连接请求时,就需要创建大量监听线程,这时如果线程没有数据就绪就会被挂起,然后进入阻塞状态。一旦发生线程阻塞,这些线程将会不断地抢夺 CPU 资源,从而导致大量的 CPU 上下文切换,增加系统的性能开销。

    具体IO的操作流程如下:

     

    • JVM 会发出 read() 系统调用,并通过 read 系统调用向内核发起读请求;
    • 内核向硬件发送读指令,并等待读就绪;
    • 内核把将要读取的数据复制到指向的内核缓存中;
    • 操作系统内核将数据复制到用户空间缓冲区,然后 read 系统调用返回。

    在这个过程中,数据先从外部设备复制到内核空间,再从内核空间复制到用户空间,这就发生了两次内存复制操作。这种操作会导致不必要的数据拷贝和上下文切换,从而降低 I/O 的性能。

     多线程下的BIO模型如上所示,需要通过serverSocket监听所有Socket接口,以便获取通知。

    NIO

    面对BIO的性能问题,操作系统以及编程语言都进行了优化,提出了非阻塞式IO模型-NIO。

    NIO是基于channel(管道)和Buffer(缓冲区)来进行操作的,程序对文件的IO操作必须通过Channel完成,而对Channel的读写必须通过Buffer。

    Selector(多路复用器)是NIO中实现非阻塞模式的关键,我们可以用它对各个通道注册比较感兴趣的事件,并调用其select()方法检查和获取各个通道中产生的响应事件的集合,必须新建连接、通道可读、通道可写。这一个机制使我们通过一个线程来一次处理这些事件,而不需要每个通道都启动一个线程。

    多路复用器的工作模式:

    Buffer(缓冲区)是IO读写都会用到缓冲区,Java提供了一个从堆外分配空间的方法 ByteBuffer.allocateDirect(1024) 以及堆内分配空间的方法 ByteBuffer.allocate(1024);两者都可以实现回收,区别是堆内存访问要比直接内存慢一点,但是便于回收;直接内存分配内存慢一点,但是分配的直接内存会在Buffer对象回收的时候回收,那意味着,如果不处罚Full GC,是不会进行垃圾回收的。

    直接内存具体操作流程如下:

     如果单纯使用 Java 堆内存进行数据拷贝,当拷贝的数据量比较大的情况下,Java 堆的 GC 压力会比较大,而使用非堆内存可以减低 GC 的压力。DirectBuffer 则是直接将步骤简化为数据直接保存到非堆内存,从而减少了一次数据拷贝。

    AIO

    java1.7之后,NIO基础上进行了改建,NIO2.0。其中最重要的就是新增了异步非阻塞IO, 即JAVA AIO。

    AIO是由操作系统在IO操作完成后主动通知调用者。在性能方面,AIO的IO过程需要充分调动操作系统参与。因此不同的操作系统存在差异,Linux通过epoll机制来模拟实现AIO,而windows操作系统则通过IOCP机制来实现AIO。

  • 相关阅读:
    python检测挖矿特征的几种方式
    python检测当前端口是否使用
    matlab界面UI设计资料
    python中struct.pack()函数和struct.unpack()函数
    网络编程:主机字节序和网络字节序
    【原创】python中文编码问题深入分析(三):python2.7文件读写中文编码问题
    【原创】python中文编码问题深入分析(二):print打印中文异常及显示乱码问题分析与解决
    ivew定制主题 less ^3.0 时报错 .bezierEasingMixin(); Inline JavaScript is not enabled. Is it set in your options?
    Vue子组件中 data 从props中动态更新数据
    Vue 自动吸顶
  • 原文地址:https://www.cnblogs.com/wangb0402/p/12704417.html
Copyright © 2020-2023  润新知