Kernel一般指实时操作系统。jvm到cpu、硬盘需要系统调用。这个东西原来这么底层。有时间必须好好研究下。IO太重要了。

下图的磁盘IO解释:
jvm进程中运行着java线程,写和读是逆过程。以写为列子,jvm写入程序缓冲区,通过flush冲刷,如果你不使用flush,那么数据将停在系统buffer中,只有冲刷后才会写入硬盘。因此这是两次拷贝。那么我们如何高效的写入内存变得很重。
IO底层概念理解
BIO (Blocking I/O):同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。这里使用那个经典的烧开水例子,这里假设一个烧开水的场景,有一排水壶在烧开水,BIO的工作模式就是, 叫一个线程停留在一个水壶那,直到这个水壶烧开,才去处理下一个水壶。但是实际上线程在等待水壶烧开的时间段什么都没有做。
NIO (New I/O):同时支持阻塞与非阻塞模式,但这里我们以其同步非阻塞I/O模式来说明,那么什么叫做同步非阻塞?如果还拿烧开水来说,NIO的做法是叫一个线程不断的轮询每个水壶的状态,看看是否有水壶的状态发生了改变,从而进行下一步的操作。
AIO ( Asynchronous I/O):异步非阻塞I/O模型。异步非阻塞与同步非阻塞的区别在哪里?异步非阻塞无需一个线程去轮询所有IO操作的状态改变,在相应的状态改变后,系统会通知对应的线程来处理。对应到烧开水中就是,为每个水壶上面装了一个开关,水烧开之后,水壶会自动通知我水烧开了。
进程中的IO调用步骤大致可以分为以下四步:
进程向操作系统请求数据 ;
操作系统把外部数据加载到内核的缓冲区中;
操作系统把内核的缓冲区拷贝到进程的缓冲区 ;
进程获得数据完成自己的功能 ;

那么我们如何高效的写入内存变得很重:
IO底层概念理解
kafka举例:
IO底层概念理解
网络多路复用:
IO底层概念理解
select 最不能忍受的是一个进程所打开的FD是有一定限制的,由FD_SETSIZE设置,默认值是1024。不过 epoll则没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左右,具体数目可以cat /proc/sys/fs/file-max查看,一般来说这个数目和系统内存关系很大。
epoll相关的系统调用有:epoll_create, epoll_ctl和epoll_wait。Linux-2.6.19又引入了可以屏蔽指定信号的epoll_wait: epoll_pwait。
其中epoll_create用来创建一个epoll文件描述符,epoll_ctl用来添加/修改/删除需要侦听的文件描述符及其事件,epoll_wait/epoll_pwait接收发生在被侦听的描述符上的,用户感兴趣的IO事件。epoll文件描述符用完后,直接用close关闭即可,非常方便。事实上,任何被侦听的文件符只要其被关闭,那么它也会自动从被侦听的文件描述符集合中删除,很是智能。

mmap (一种内存映射文件的方法):
mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。mmap在用户空间映射调用系统中作用很大。

NIO buffer的三个位置:
IO底层概念理解
heap内:allocate
堆外内存空间:allocateDirect
mmap(堆外,内核直接访问,不需要触发拷贝):wrap

kafka分析:
IO底层概念理解
IO与内存的关系。需要自己去重点学习下。

BIO模型:调用内核函数read()
IO底层概念理解
Socket是内核级别的,socket本身支持非阻塞和阻塞,取决于放入的io。

利用用户空间程序轮询连接这就叫NIO
IO底层概念理解
但是连接特别多的时候,轮询的效率就变得地下。

多路复用NIO:
为了改善上面的问题:内核函数select出现了。用户带来,用户只调用一次,调用select,服务器去轮询发现建立连接,可读,就发送消息。
IO底层概念理解
上面也有问题,复制太多了。
将复制砍掉,采用epoll直接mmap内存。
IO底层概念理解
所以历史发展,阻塞-非阻塞-多路复用。

相关文章: