企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[TOC] > 本节总结一下,我们在学习Socket编程的时候,需要知道的一些基础性概念。 ## 什么是NIO ![](https://img.kancloud.cn/72/38/72382626bae77ad1aff38b434364ffe8_244x172.png) `NIO(non-blocking)`,使用较少的Thread线程,通过Selector选择器来执行不同Channel通道中的任务,执行的任务再结合AIO(异步I/O)就能发挥服务器最大的性能,大大提升软件运行效率。 ### 解释一下NIO为啥叫做同步非阻塞 同步和异步关注的是消息通信机制,阻塞和非阻塞关注的是程序在等待调用结果时的状态。 首先一个I/O操作其实分成了两个步骤: 1. 发起I/O请求——关注程序在等待调用结果时的状态(调度过程);NIO在调度过程中是非阻塞的,无需等待线程执行完读写; 2. 实际的I/O操作——关注消息通信机制。NIO线程处理由selector分配的任务过程是同步的。 ### NIO性能为什么好? > 结合缓冲区~ #### 1. 零拷贝 NIO零拷贝适用于以下场景: 1. 文件较大,读写较慢,追求速度 2. JVM内存不足,不能加载太大数据 3. 内存带宽不够,即存在其他程序或线程存在大量的IO操作,导致带宽本来就小 #### 2. 直接内存映射 ![](https://img.kancloud.cn/d5/d3/d5d3941388943a2144a6b257231b4bc4_511x383.png) 直接内存,目的是防止Java堆和Native堆之间数据复制带来的性能损耗,此后NIO可以使用Native的方式直接在 Native堆分配内存。 ### 使用直接内存的原因 1. 对垃圾回收停顿的改善。因为full gc时,垃圾收集器会对所有分配的堆内内存进行扫描,垃圾收集对Java应用造成的影响,跟堆的大小是成正比的。过大的堆会影响Java应用的性能。如果使用堆外内存的话,堆外内存是直接受操作系统管理。这样做的结果就是能保持一个较小的JVM堆内存,以减少垃圾收集对应用的影响。(full gc时会触发堆外空闲内存的回收。) 2. 减少了数据从JVM拷贝到native堆的次数,在某些场景下可以提升程序I/O的性能。 3. 可以突破JVM内存限制,操作更多的物理内存。 ## 通道(Channel) 通道是用于I/O操作的连接,更具体地讲,通道代表数据到硬件设备、文件、网络套接字的连接。通道可处于打开或关闭这两种状态,当创建通道时,通道就处于打开状态,一旦将其关闭,则保持关闭状态。一旦关闭了某个通道,则试图对其调用I/O操作时就会导致ClosedChannel Exception异常被抛出,但可以通过调用通道的isOpen()方法测试通道是否处于打开状态以避免出现ClosedChannelException异常。一般情况下,通道对于多线程的访问是安全的。 ## 单播、广播、多播 - 单播。所谓的单播大多数都是点对点式的网络,如打开网页、发送邮件和两人网络聊天等情况,都是在使用点对点方式传输数据。 - 广播。广播是一种一对多的形式,是对网络中所有的计算机发送数据,不区分目标,这就极易造成网络中存在大量无用的垃圾通信数据,造成“广播风暴”,使网络变慢,严重时网络会彻底瘫痪。 - 多播也称为组播,它也是一种一对多的网络。从组播的名字来看,它可以对某些计算机分配多播类型的IP地址以进行分组,然后只针对这些计算机发送数据,这就是多播。