2.2磁盘IO网络IO工作机制
磁盘I/O工作机制:访问文件
在Java中,读 & 写对应了 read() & write() 两个系统调用,但只要系统调用,就会存在内核空间地址和用户空间地址切换的问题(操作系统为了保护系统安全,必须将内存空间和用户空间进行隔离),因为数据可能需要从内核空间向用户空间复制。
如果遇到了非常耗时的操作,如磁盘I/O,数据得从磁盘–>内核空间–>用户空间,复制了两遍,将会非常缓慢。
因此操作系统在内核空间加入了缓存机制,也就是说:如果用户程序访问的是同一段磁盘地址的数据,将会从上一次在内核空间的缓存中直接取得,这样就只复制了一次。
接下来会介绍几种访问文件的方式:
标准访问文件方式
当调用read()接口时,操作系统检查在内核的高速缓存中有没有数据,如果有就直接返回;否则从磁盘中读取,然后再缓存在内核中。
当调用write()接口时,数据从用户地址空间–>内核地址空间的缓存中,操作完成。
至于什么时候写到磁盘,由操作系统决定,除非调用sync同步,强制写入磁盘中。
用户地址空间内核地址空间物理磁盘应用缓存1应用缓存2高速页缓存1高速页缓存2磁盘数据read方法write方法直接I/O方式
- 程序直接访问磁盘数据,不经过操作系统内核,这样做能够减少一次数据复制。
- y优点:适用与由程序实现~~(而不是操作系统)~~的数据库管理系统等,因为操作系统不知道应该缓存哪些数据、失效哪些数据,但是程序知道。
- 缺点:如果访问的数据不在缓存中,那么每次都会直接从磁盘加载,而这种加载相对非常慢,多次之后会变得十分低效。
用户地址空间内核地址空间物理磁盘应用缓存1应用缓存2高速页缓存1高速页缓存2磁盘数据read方法write方法同步访问文件方式
- 数据的读&写都是同步操作,和标准访问不同的是:只有当数据被成功写到磁盘时,才返回标志给应用程序
- 性能差,只针对于数据安全性要求高的场景,通常由硬件完成
用户地址空间内核地址空间物理磁盘应用缓存1应用缓存2高速页缓存1高速页缓存2磁盘数据read方法write方法异步访问文件方式
- 当访问数据的线程发出请求后,线程会接着处理其他事情,而不是阻塞(等待),只有当数据返回时才继续处理后续操作。
- 能提高程序效率,但不是访问文件的效率
用户地址空间内核地址空间物理磁盘应用缓存1应用缓存2高速页缓存1高速页缓存2磁盘数据read方法write方法内存映射方式
- 将操作系统内存中的某块区域和磁盘中的文件夹关联,访问内存时转化为访问磁盘文件的某段数据(和直接IO的区别就是这个映射,相当于一个定位,就快的多)
- 目的是减少数据的复制操作,此时这两个空间的数据都相当于是共享的
用户地址空间内核地址空间物理磁盘地址映射地址映射应用缓存1应用缓存2高速页缓存1高速页缓存2磁盘数据read方法write方法
Java序列化&反序列化
Java序列化就是将一个对象转化为一串二进制的字节数组,然后通过保存这个字节数组进行持久化。而且达到持久化的目的,必须实现java.io.Serializable接口。
Java反序列化就是将字节数组再重新构造成对象。
序例化对象
要序例化一个对象,分如下步骤:
- 创建某种OutputStream对象,然后将其封装在一个ObjectOutputStream对象内
- 调用writeObject()即可将对象序列化(对象序列化基于字节,因此使用InputStream和OutputStream继承类层次结构)。
反序列化和序列化过程正好相反,需要将一个InputStream封装在ObjectInputStream内,然后调用readObject()获取一个引用,它指向一个向上转型的Object,所以必须向下转型才能直接设置它们。
对于序列化对象的代码:
public class Serialize implements Serializable {public int num = 1;public long id = 777;public static void main(String[] args) throws IOException {//初始化FileOutputStream fos = new FileOutputStream("filepath");ObjectOutputStream oos = new ObjectOutputStream(fos);//开始干事情Serialize sl = new Serialize();//我自己写的对象oos.writeObject(Serialize);oos.flush();oos.close();}
}
另外,在纯Java环境下,Java序列化能够很好地工作;但是在多语言环境下,会出问题,尽量还是用JSON或XML这些通用的数据结构。
网络I/O工作机制
基础知识
首先你得懂TCP的三次握手和四次挥手,在《计算机网络》中有详细说明,不做过多解释。
要想加速网络的I/O,首先要分析一下影响网络的因素:
- 网络带宽:1s内能传输的最大比特数,平均网络带宽为1.7Mb/s
- 传输距离:也就是数据要在光纤中走的距离,因为有一个折射率,所以大概只有光速的2/3,比如杭州和青岛的两台机子进行同步操作必定会有一个30ms的延时
- TCP拥塞控制:详细见《计算机网络》
Java Socket工作机制
Socket 是描述计算机之间完成相互通信一种抽象功能。下面将通过一组比喻&一张图让你了解Socket的工作机制:
- 两台主机=两个城市
- 物理链路=高速通道
- Socket=交通工具
- 要交付的数据=要运输的货物
- 通信协议=交通工具的相关规则(比如说电动车不准上高速[狗头])
大致过程:
但是一台主机上可能运行着多个应用程序,所以,就要通过 TCP 或 UDP 的地址也就是端口号来指定,端口号又对应一个Socket。这样就可以通过一个 Socket 实例,唯一代表一条通信链路了。下面将具体介绍是如何建立链路的。
建立通信链路
当客户端要与服务端通信:
在客户端
- 客户端首先要创建一个 Socket 实例,操作系统将为这个 Socket 分配一个端口号(port)
- 创建一个套接字数据结构,包含本地和远程地址&端口号。(这个数据结构将一直保存在系统中直到这个连接关闭)
- 进行 TCP 的三次握手协议
- Socket 实例的构造函数正确返回,Socket 实例对象就宣布正式创建完成,否则将抛出 IOException 错误。
在服务端
服务端将创建一个 ServerSocket 实例(比较简单,只要端口号未占用,一般实例创建都会成功)
操作系统也会为 ServerSocket 实例创建一个底层数据结构,包含指定监听的端口号和包含监听地址的通配符(通常情况下都是“*”即监听所有地址)
调用 accept() 方法时,进入阻塞状态,等待客户端的请求。
当一个新的请求到来时,将为这个连接创建一个新的套接字数据结构(包含请求源地址和端口)。
这个数据结构,将会关联到 ServerSocket 实例的一个未完成的连接“数据结构“列表中(注意这时服务端与之对应的 Socket 实例并没有正式创建完成,待三次握手完成后,就会将这个 Socket 实例对应的数据结构从未完成列表中移到已完成列表中)
所以 ServerSocket 所关联的列表中每个数据结构,都代表与一个客户端的建立的 TCP 连接(无论是否完成)
数据传输
传输数据是我们建立连接的主要目的,如何通过 Socket 传输数据,下面将详细介绍。
当连接已经建立成功,服务端和客户端都会拥有一个 Socket 实例,两边的 Socket 实例都有一个 InputStream 和 OutputStream,正是通过这两个对象来交换数据。
当 Socket 对象正式创建完毕时,操作系统将会为 InputStream 和 OutputStream 分别分配一定大小的缓冲区,以便数据的写入和读取
写入端将数据写到 OutputStream 对应的 SendQ 队列中,当队列填满时,数据就将会一起发送,到读取端的InputStream 的 RecvQ 队列中。(如果这时 RecvQ 已经满了,那么 OutputStream 的 write 方法将会阻塞直到 RecvQ 队列有足够的空间容纳 SendQ 发送的数据)
注意:
- 这个缓存区的大小&写入端的速度&读取端的速度,非常影响该连接的数据传输效率,所以在写入和读取还要有一个协调的过程
- 如果两边同时传送数据时可能会产生死锁,在后面 NIO 部分将介绍避免这种情况。
2.2磁盘IO网络IO工作机制相关推荐
- Linux命令进阶-cpu监控内存监控文件IO网络IO性能分析
Linux命令进阶-cpu监控内存监控文件IO网络IO性能分析 前言 1 linux基础命令 1.1 grep 1.2 ls 1.3 find 1.4 ulimit 1.5 curl 1.6 scp ...
- 实战:如何对磁盘和网络IO进行评估、监控、定位和优化?
点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取 后台回复"k8s",可领取k8s资料 生产中经常遇到一 ...
- 深入分析 Java I/O 的工作机制--转载
Java 的 I/O 类库的基本架构 I/O 问题是任何编程语言都无法回避的问题,可以说 I/O 问题是整个人机交互的核心问题,因为 I/O 是机器获取和交换信息的主要渠道.在当今这个数据大爆炸时代, ...
- JavaWeb技术内幕二:Java IO工作机制
IO问题是当今web应用所面临的主要问题之一,因为数据在网络中随处流动,在这个流动过程中都涉及IO问题,并且大部分应用的瓶颈都是IO瓶颈. 本章将从IO的角度出发,介绍IO类库的基本架构,磁盘IO的工 ...
- 详解磁盘IO、网络IO、零拷贝IO、BIO、NIO、AIO、IO多路复用(select、poll、epoll)
文章很长,但是很用心! 文章目录 1. 什么是I/O 2. 磁盘IO 3. 网络IO 4. IO中断与DMA 5. 零拷贝IO 6. BIO 7. NIO 8. IO多路复用 8.1 select 8 ...
- 网络模型——四种常见网络IO模型
文章目录 1.IO读写原理 1.1 内核缓冲区和进程缓存区 1.1.1 用户进程和操作系统 1.1.2 缓冲区的目的 1.2 Java读写IO底层流程 2.四种主要的IO模型 2.1 基本概念 2.1 ...
- 后端开发【一大波有用知识】网络通信模型和网络IO管理
简单的C/S通信模型(accept阻塞的话,就只能一个客户端接进来) socket()函数 //函数原型.返回:若是成功则为非负数,如出错则为 -1 int socket(int domin, int ...
- 深入分析 Java I/O 的工作机制
深入分析 Java I/O 的工作机制 I/O 问题是任何编程语言都无法回避的问题,可以说 I/O 问题是整个人机交互的核心问题,因为 I/O 是机器获取和交换信息的主要渠道.在当今这个数据大爆炸时代 ...
- 分布式计算 MapReduce与yarn工作机制
一.第一代hadoop组成与结构 第一代Hadoop,由分布式存储系统HDFS和分布式计算框架MapReduce组成,其中,HDFS由一个NameNode和多个DataNode组成,MapReduce ...
- 深入了解Java I/O的工作机制
Java I/O操作类 在i/o类中有将近80个类,大致分为四组 1.基于字节操作的I/O接口:InputStream和OutStream 2.基于字符操作的I/O接口:Writer和Reader 3 ...
最新文章
- 基于Android5.0的Camera Framework源码分析 (三)
- js json对象转字符串_Mock.js模拟数据实现前端独立开发
- IEnumerableT和IQueryableT区分
- 1092 最好吃的月饼 (20 分
- Java加密与解密的艺术~数字证书~模型分析
- 统计数字字符和空格 (15 分)
- Bootstrap3 带表格的面板
- html5晋级之路-学习笔记表单
- 7.28-说说对javaweb的感想吧
- postman下载安装汉化及使用
- PROE 安装提示注册号丢失
- 生化危机4重生 java_生化危机-绝密报告4
- pixel 刷入自己编译的Android 8.0 安装Xposed 显示 Verified Boot (dm-verity) prevents the device from booting
- ARIMA模型的拖尾截尾问题
- 武汉新时标文化传媒有限公司短视频的类型
- 如何通过组策略统一为公司电脑设置“兼容性视图设置”
- 计算机标记的定义,标记网格法
- GA001-181-14
- Illustrator “图像裁切”功能如何使用?
- ADS1.2+2440+j-link(亲测)
热门文章
- iPhone查询商品历史价格详细教程
- python教程cos_Python爬虫入门教程 12-100 半次元COS图爬取
- 计算机操作系统(2)
- 服务器sni协议,关于 https 的 SNI(Sever Name Indication) 问题记录
- 知识体系结构---备份
- 工资,一般讲税前还是税后?
- 《霍乱时期的爱情》摘要
- centos:/usr/bin/perl is needed by mysql-community-server
- linux中为什么要分区,为什么要分区
- HUSTOJ超级详细部署文档