直接内存
在操作系统里面,在读写的时候,有一个输入缓冲区和一个输出缓冲区,然后操作系统内部也有一个C堆(操作系统层面的堆,用C语言写的堆,现在简称C堆).
对于虚拟机来讲,jvm里面也有所谓的堆,如果我们进行网络读写的时候,我们在jvm里面的堆进行一个内存空间的分配,当我们真正要把一个数据从虚拟机堆内存通过网络传递的时候要经过下面几步:
1. 虚拟机的堆先到操作系统的堆
2. 操作系统的堆再把这个请求发送到输入输出缓冲区,最后经过网络发送出去.
为什么网络编程要引入直接内存呢?
从虚拟机的堆,到操作系统的C堆这只是一个简单的拷贝过程而已,中间没有任何的复杂计算操作,只是简单的内存拷贝,有没有什么办法取消掉jvm堆从操作系统C堆里面拷贝数据?
于是就引入了直接内存的概念.
在操作系统的C堆里面我们马上就分配一个所谓的空间(ByteBuffer)出来,我们的所有的读写操作直接对C堆的ByteBuffer进行操作,等待要发送数据的时候,直接由C堆里面的ByteBuffer直接发送到输出缓冲区或者输入缓冲区里面,这就省去了jvm堆从操作系统C堆里面拷贝数据的一步骤.这样对网络读写的性能肯定是有提升的.
1.堆外内存的优点和缺点
堆外内存,其实就是不受JVM控制的内存。相比于堆内内存有几个优势:
1 减少了垃圾回收的工作,因为垃圾回收会暂停其他的工作(可能使用多线程或者时间片的方式,根本感觉不到)
2 加快了复制的速度。因为堆内在flush到远程时,会先复制到直接内存(非堆内存),然后在发送;而堆外内存相当于省略掉了这个工作。
而福之祸所依,自然也有不好的一面:
1 堆外内存难以控制,如果内存泄漏,那么很难排查
2 堆外内存相对来说,不适合存储很复杂的对象。一般简单的对象或者扁平化的比较适合。
2.直接内存(堆外内存)与堆内存比较
直接内存申请空间耗费更高的性能,当频繁申请到一定量时尤为明显
直接内存IO读写的性能要优于普通的堆内存,在多次读写操作的情况下差异明显