BlazeMaple BlazeMaple
首页
  • 基础知识

    • Java的基本数据类型
    • Java中的常用类String
    • Java中的异常
    • Java中的注解
    • Java中的反射机制
    • Java中的泛型
    • Java为什么是值传递
  • 集合框架

    • Java集合核心知识总结
    • HashMap的7种遍历方式
    • 源码分析
  • Java新特性

    • Java8新特性
  • IO流

    • Java基础IO总结
    • Java IO中的设计模式
    • Java IO模型
    • IO多路复用详解
  • 并发编程

    • 并发编程基础总结
  • JVM

    • JVM基础总结
  • MySQL

    • MySQL核心知识小结
    • MySQL 45讲
  • Redis

    • Redis核心入门知识简记
  • Spring
  • SpringCloud Alibaba
  • 开发工具

    • Git详解
    • Maven详解
    • Docker详解
    • Linux常用命令
  • 在线工具

    • json (opens new window)
    • base64编解码 (opens new window)
    • 时间戳转换 (opens new window)
    • unicode转换 (opens new window)
    • 正则表达式 (opens new window)
    • md5加密 (opens new window)
    • 二维码 (opens new window)
    • 文本比对 (opens new window)
  • 学习资源

    • 计算机经典电子书PDF
    • hot120
GitHub (opens new window)
首页
  • 基础知识

    • Java的基本数据类型
    • Java中的常用类String
    • Java中的异常
    • Java中的注解
    • Java中的反射机制
    • Java中的泛型
    • Java为什么是值传递
  • 集合框架

    • Java集合核心知识总结
    • HashMap的7种遍历方式
    • 源码分析
  • Java新特性

    • Java8新特性
  • IO流

    • Java基础IO总结
    • Java IO中的设计模式
    • Java IO模型
    • IO多路复用详解
  • 并发编程

    • 并发编程基础总结
  • JVM

    • JVM基础总结
  • MySQL

    • MySQL核心知识小结
    • MySQL 45讲
  • Redis

    • Redis核心入门知识简记
  • Spring
  • SpringCloud Alibaba
  • 开发工具

    • Git详解
    • Maven详解
    • Docker详解
    • Linux常用命令
  • 在线工具

    • json (opens new window)
    • base64编解码 (opens new window)
    • 时间戳转换 (opens new window)
    • unicode转换 (opens new window)
    • 正则表达式 (opens new window)
    • md5加密 (opens new window)
    • 二维码 (opens new window)
    • 文本比对 (opens new window)
  • 学习资源

    • 计算机经典电子书PDF
    • hot120
GitHub (opens new window)
  • IO流

    • Java基础IO总结
    • Java IO中的设计模式
    • Java IO模型
      • 什么是IO?
      • 深入内核理解网络数据包IO过程
        • 网络数据包接收过程
        • 网络数据包发送过程
      • Java中常见的IO模型
        • BIO (Blocking I/O)
        • NIO(Non-blocking/New I/O)
        • 同步非阻塞IO模型
        • I/O 多路复用模型
        • AIO (Asynchronous I/O)
      • 总结
    • IO多路复用详解
  • 并发编程

    • 并发编程基础总结
    • 深入理解volatile关键字
    • 深入理解synchronized关键字
  • JVM

    • JVM基础总结
  • Java进阶
  • IO流
BlazeMaple
2023-12-12
目录

Java IO模型

# 什么是IO?

冯诺伊曼提出的计算机体系结构由输入和输出、以及运算器、控制器、存储器构成。

在这里插入图片描述

实际上IO就是计算机与外部设备数据交互的过程。为了保证操作系统的稳定性和安全性,操作系统会将空间分为用户空间和内核空间。 我们平常所运行的程序都处于用户态,当我们需要进行文件管理、进程通信、内存管理,都需要从用户态转为内核态执行才能执行这些特权指令。并且,用户空间的程序不能直接访问内核空间。当想要执行 IO 操作时,由于没有执行这些操作的权限,只能发起系统调用请求操作系统帮忙完成。因此,用户进程想要执行 IO 操作的话,必须通过 系统调用 来间接访问内核空间

所以我们应用程序执行IO时,会进行以下步骤:

  1. 应用程序发起IO请求,这个特权指令会从用户态转到内核执行。
  2. 内核等待IO准备好数据。
  3. 内核IO数据准备完毕,将数据从内核空间拷贝用户空间。

# 深入内核理解网络数据包IO过程

# 网络数据包接收过程

如下图所示,自底向上,首先收到一个网络包后首先会到达网卡,然后通过DMA(直接存储器访问)环形缓冲区。完成数据拷贝之后,发起一次硬中断通知CPU有网络数据来了。然后CPU将这个数据拷贝到sk_buffer,再发起一次软中断将数据向上传输。注意,若有多个CPU则哪个CPU发起硬中断,则就是哪个CPU发起软中断。然后就是不断解数据包头的过程,数据会不断解包,以下图为例,我们得知最终的报文是一个TCP数据包,我们就会根据socket四元组将数据拷贝到socket缓冲区,反之返回一个目的不可达的icmp包。 最后数据从socket缓冲区拷贝到用户数据区read返回。

在这里插入图片描述

性能开销大在这几处:

  1. DMA拷贝到内存的开销。
  2. 硬中断的开销。
  3. 软中断的开销。
  4. 网络数据从内核空间拷贝到用户空间的开销。
  5. 整个调用过程从用户态转内核态再从内核态转为内核态的过程。

# 网络数据包发送过程

发送过程和接收过程类似,整体如下:

  1. 应用程序发起send请求,将数据从用户空间拷贝到内核空间。
  2. 封装成struct msghdr对象加入socket队列中
  3. 需要发送时进行封装处理。
  4. 然后经过软中断、硬中断到达硬件层发送出去

在这里插入图片描述

# Java中常见的IO模型

# BIO (Blocking I/O)

BIO 属于同步阻塞 IO 模型 。同步阻塞 IO 模型中,应用程序发起 read 调用后,会一直阻塞,直到内核把数据拷贝到用户空间

在客户端连接数量不高的情况下,是没问题的。但是,当面对十万甚至百万级连接的时候,传统的 BIO 模型是无能为力的。因此,我们需要一种更高效的 I/O 处理模型来应对更高的并发量。

图源:《深入拆解Tomcat & Jetty》

# NIO(Non-blocking/New I/O)

Java 中的 NIO 可以看作是 I/O 多路复用模型,很多人它属于同步非阻塞模型,其实不对,如下说明两者区别

# 同步非阻塞IO模型

同步非阻塞 IO 模型中,应用程序会一直发起 read 调用,等待数据从内核空间拷贝到用户空间的这段时间里,线程依然是阻塞的,直到在内核把数据拷贝到用户空间。相比于同步阻塞 IO 模型,同步非阻塞 IO 模型确实有了很大改进。通过轮询操作,避免了一直阻塞。但是,这种 IO 模型同样存在问题:应用程序不断进行 I/O 系统调用轮询数据是否已经准备好的过程是十分消耗 CPU 资源的。

在这里插入图片描述

# I/O 多路复用模型

IO 多路复用模型中,线程首先发起 select 调用,询问内核数据是否准备就绪,等内核把数据准备好了,用户线程再发起 read 调用。read 调用的过程(数据从内核空间 -> 用户空间)还是阻塞的。

img

IO 多路复用模型,通过减少无效的系统调用,减少了对 CPU 资源的消耗。

Java 中的 NIO ,有一个非常重要的选择器 ( Selector ) 的概念,也可以被称为 多路复用器。通过它,只需要一个线程便可以管理多个客户端连接。当客户端数据到了之后,才会为其服务。

# AIO (Asynchronous I/O)

AIO 也就是 NIO 2。Java 7 中引入了 NIO 的改进版 NIO 2,它是异步 IO 模型。异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。

img

# 总结

在这里插入图片描述

帮助我们改善此页面! (opens new window)
上次更新: 2024/08/13, 09:07:12
Java IO中的设计模式
IO多路复用详解

← Java IO中的设计模式 IO多路复用详解→

最近更新
01
SpringCloud Alibaba实战
08-22
02
SpringCloud Alibaba核心知识
08-22
03
两数之和
08-08
更多文章>
Theme by Vdoing | Copyright © 2023-2024 BlazeMaple
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式