在我们讨论java的内存模型时,和讨论java的NIO时都会涉及到直接缓冲和非直接缓冲区这个概念(主要是直接和非直接)
在java的内存模型中https://blog.csdn.net/qiuwenjie123/article/details/79200509
会有堆和直接内存这个概念,堆就存在于jvm的内存之中,而直接内存则是不属于与jvm的工作内存之中,相当于另外的内存
而在NIO中https://blog.csdn.net/qiuwenjie123/article/details/79130324
同理会说到这两种缓存
非直接缓存很好理解,就把他当成一个缓存就好了,那么直接缓存有什么用,优缺点是什么?
直接贴出我百度的结果吧
正常情况下,JVM创建一个缓冲区的时候,实际上做了如下几件事:
1.JVM确保Heap区域内的空间足够,如果不够则使用触发GC在内的方法获得空间;
2.获得空间之后会找一组堆内的连续地址分配数组, 这里需要注意的是,在物理内存上,这些字节是不一定连续的;
3.对于不涉及到IO的操作,这样的处理没有任何问题,但是当进行IO操作的时候就会出现一点性能问题.
所有的IO操作都需要操作系统进入内核态才行,而JVM进程属于用户态进程, 当JVM需要把一个缓冲区写到某个Channel或Socket的时候,需要切换到内核态.
而内核态由于并不知道JVM里面这个缓冲区存储在物理内存的什么地址,并且这些物理地址并不一定是连续的(或者说不一定是IO操作需要的块结构),所以在切换之前JVM需要把缓冲区复制到物理内存一块连续的内存上, 然后由内核去读取这块物理内存,整合成连续的、分块的内存.
也就是说如果我们这个时候用的是非直接缓存的话,我们还要进行“复制”这么一个操作,而当我们申请了一个直接缓存的话,因为他本是就是一大块连续地址,我们就可以直接在它上面进行IO操作,省去了“复制”这个步骤
当然缺点也是有的,他的分配和释放都比较昂贵,相对于非直接缓存而言