网络编程-NIO 理论部分

2020-02-16  本文已影响0人  白璞1024

NIO- no_block IO 或者叫NewIO JAVA 1.4引入的

1 、NIO和BIO的区别

1.1、面向流和面向缓存

1.2、阻塞与非阻塞

1.3、Select

2、selector

selector选择器,轮训代理器,事件订阅器,channel容器管理器

应用程序将select对象注册需要它关注的Channel,以及具体的某一个Channel会对哪些IO事件感兴趣,Selector中也会维护一个已经注册的Channel的容器。

3、Channels

通道,被建立的一个应用程序和操作系统交互事件,传递内容的渠道,注意是连接到操作系统的 程序可以通过通道读取数据,也可以通过通道向操作系统写数据,而且可以同时进行读写。

通道中的数据总是要先读到一个Buffer或者,总是要从一个Buffer中写入

4、SelectionKey

select对象注册感兴趣的事件的时候,JAVA NIO共定义了四种 OP_READ、OP_WRITE、OP_CONNECT、 OP_ACCEPT

四、Buffer

用来和NIO通道进行交互,数据是从通道读入缓存区,缓存去写入到通道中的。以写为例:应用程序都是将数据写入缓存,在通过通道把数据发出去,读也是一样的。缓存本质上就是一个可以写入数据,然后可以读取数据的内存。这块内存被包装成NIO Buffer的对象,提供了一组方法,用来方便的访问这块内存。

1、重要属性

  1. capacity

内存卡,Buffer又一个固定的大小,就是capacity,一旦满了,需要清空(读数据,清除数据) 才能继续往里写数据。

  1. position

    当你写数据到Buffer中的时候,position表示当前的位置,初始position值是0.当一个byte, long,等数据写到Buffer后,position会向前移动到下一个可插入数据的Buffer单元。position最大可为capacity-1。读取数据的时候,也是也是从一个特定的位置开始读,Buffer写模式换成读模式的时候,position会重置成0档从Buffer的postion处读取数据的时候,position向前移动到下一个可读到位置。

  2. limit

    写模式下,Buffer的limit表示你最多能往Buffer里写多少的数据。写模式下,limit等于Buffer的capacity

    读模式下,Buffer到读模式的时候,limit表示你最多能读多少数据。切换Buffer到读模式的时候,limit会被设置成写模式的下的position值。你能读到之前写入的所有的数据。

2、Buffer的分配

想要活的一个Buffer对象首先要进行分配,每一个Buffer类都有allocate方法,可以在堆上分配,也可以直接内存上分配。

ByteBuffer buf = ByteByffer.allocate(48);//分配48字节的
CharBuffer buf = CharBuffer.allocate(1024);

把一个byte数组或者是byte数组的一部分包装成ByteBuffer

ByteBuffer wrap(byte[] array)
ByteBuffer wrap(butep[] array,int office,int length); 

HeapByteBufferDirectByteBuffer原理上,前者可以看出分配的buffer是在heap区域的,其实真正的flush到远程的时候,会先复制到直接内存,再做下一步操作。

NIO框架下,很多框架会采用DirectByteBuffer来操作,这样内存不再是heap上,而是操作在系统的C heap上,经过性能测试,可以得到非常快的网络交互。大量的网络交互下,一般速度会比HeapByteBuffer快速好几倍。

直接内存(Di re c t M e me o r y)并不是虚拟机运行时候数据区的一部分,也不是java虚拟机规范中定义的内存区域。这部分内存频繁的被使用,也可以导致OurOfMemoryError出现。NIO可以使用Native函数库直接分配对外内存,然后通过一个存储在java堆里边的DirectByteBuffer对象作为这个内存的应用进行处理

>1 堆外内存优缺点

相比较堆内内存有几个优势:

  1. 减少了垃圾回收的工作,因为垃圾回收会暂停其他的工作。
  2. 加快了复制的速度。省略了堆内flush到远程的时候,先复制到直接内存的过程;

不好的一面

  1. 难以控制,如果内存泄露,很难排查
  2. 不适合存储很复杂的对象,一般简单的对象或者是扁平化的比较合适。

>2 直接内存(堆外内存)与堆内存的比较

​ 直接内存申请空间耗费更多的性能。频繁处理的时候这一点很明显

​ 直接内存IO速度性能优于普通内存。多次读写操作的情况下,差异明显

3、Buffer的读写

1. 向Buffer中写数据

两种方式:

2. 从Buffer中读取数据

使用Buffer读写数据常见步骤

  1. 写入数据到Buffer
  2. 调用flip()方法
  3. Buffer中读取数据
  4. 调用clear()方法或者 compact()方法,清除掉缓存中的数据。
上一篇下一篇

猜你喜欢

热点阅读