关于Nio的直接与 非直接缓冲区的理解
jdk对nio的ByteBuffer 有allocate 和 allocateDirect
解释为:
字节缓冲区要么是直接的,要么是非直接的。如果为直接字节缓冲区,则 Java 虚拟机会尽最大努力直接在此缓冲区上执行本机 I/O 操作。也就是说,在每次调用基础操作系统的一个本机 I/O 操作之前(或之后),虚拟机都会尽量避免将缓冲区的内容复制到中间缓冲区中(或从中间缓冲区中复制内容)。
其allocateDirect分配jvm堆外内存
虚拟机都会尽量避免将缓冲区的内容复制到中间缓冲区中
这个中间缓冲区如何理解,这个过程是如何进行的呢?查阅很久也没明白
我之前理解是allocateDirect是直接在内核空间的缓存区如:page cache中直接分配?避免jvm的进程空间的数据与内核cache的复制,但是网上很多没有这个解释。希望大家能帮我解惑。得到标准的答案?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
非直接缓冲区写入步骤:
1.创建一个临时的直接ByteBuffer对象。
2.将非直接缓冲区的内容复制到临时缓冲中。
3.使用临时缓冲区执行低层次I/O操作。
4.临时缓冲区对象离开作用域,并最终成为被回收的无用数据。
如果采用直接缓冲区会少一次复制过程,如果需要循环使用缓冲区,用直接缓冲区可以很大地提高性能。虽然直接缓冲区使JVM可以进行高效的I/o操作,但它使用的内存是操作系统分配的,绕过了JVM堆栈,建立和销毁比堆栈上的缓冲区要更大的开销。
朋友这是问答区,你发这些有啥用嘛(自问自答?),写到你的博客里把
回复
不是呀,我就是不理解,希望有人能分析清楚点?
顶
这是文档的描述的嘛,如你所描述: 避免在java堆和Native堆来回复制数据: 那就是说,普通的IO,和未使用直接内存的NIO。 在做IO操作的时候,都会从进行复制,那这个参与复制的另一个主体:Native堆是干嘛的,为什么要复制,复制了的作用,该Native堆是谁管理的,如何与外设(磁盘,网络)交互?
回复
这个没法回答你,应该是操作系统和Java虚拟机相关的
直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError异常出现。
JDK1.4加的NIO中,ByteBuffer有个方法是allocateDirect(int capacity) ,这是一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。
你想知道的答案