关于Nio的直接与 非直接缓冲区的理解

晓残云 发布于 2015/06/05 13:02
阅读 2K+
收藏 1
JDK

jdk对nio的ByteBuffer 有allocate 和 allocateDirect

解释为:

字节缓冲区要么是直接的,要么是非直接的。如果为直接字节缓冲区,则 Java 虚拟机会尽最大努力直接在此缓冲区上执行本机 I/O 操作。也就是说,在每次调用基础操作系统的一个本机 I/O 操作之前(或之后),虚拟机都会尽量避免将缓冲区的内容复制到中间缓冲区中(或从中间缓冲区中复制内容)。 

allocateDirect分配jvm堆外内存

虚拟机都会尽量避免将缓冲区的内容复制到中间缓冲区中

这个中间缓冲区如何理解,这个过程是如何进行的呢?查阅很久也没明白

我之前理解是allocateDirect是直接在内核空间的缓存区如:page cache中直接分配?避免jvm的进程空间的数据与内核cache的复制,但是网上很多没有这个解释。希望大家能帮我解惑。得到标准的答案?

加载中
1
首席撸出血
首席撸出血

直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError异常出现。

JDK1.4加的NIO中,ByteBuffer有个方法是allocateDirect(int capacity) ,这是一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。






你想知道的答案

首席撸出血
首席撸出血
回复 @晓残云 : 这个没法回答你,应该是操作系统和Java虚拟机相关的
晓残云
晓残云
这是文档的描述的嘛,如你所描述: 避免在java堆和Native堆来回复制数据: 那就是说,普通的IO,和未使用直接内存的NIO。 在做IO操作的时候,都会从进行复制,那这个参与复制的另一个主体:Native堆是干嘛的,为什么要复制,复制了的作用,该Native堆是谁管理的,如何与外设(磁盘,网络)交互?
0
晓残云
晓残云
晓残云
回复 @首席撸出血 : 不是呀,我就是不理解,希望有人能分析清楚点?
首席撸出血
首席撸出血
朋友这是问答区,你发这些有啥用嘛(自问自答?),写到你的博客里把
0
sea
sea
非直接缓冲区写入步骤:
1.创建一个临时的直接ByteBuffer对象。
2.将非直接缓冲区的内容复制到临时缓冲中。
3.使用临时缓冲区执行低层次I/O操作。
4.临时缓冲区对象离开作用域,并最终成为被回收的无用数据。
如果采用直接缓冲区会少一次复制过程,如果需要循环使用缓冲区,用直接缓冲区可以很大地提高性能。虽然直接缓冲区使JVM可以进行高效的I/o操作,但它使用的内存是操作系统分配的,绕过了JVM堆栈,建立和销毁比堆栈上的缓冲区要更大的开销。
返回顶部
顶部