非直接缓冲区与直接缓冲区
Posted 编程老高
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了非直接缓冲区与直接缓冲区相关的知识,希望对你有一定的参考价值。
allocate(int capacity):
作用:创建指定大小的非直接缓冲区对象,该缓冲区直接建立在JVM内存中;
源码:
package java.nio;
...省略...
public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer>{
...省略...
public static ByteBuffer allocate(int capacity) {
if (capacity < 0)
throw createCapacityException(capacity);
return new HeapByteBuffer(capacity, capacity, null);
}
...省略...
}
package java.nio;
class HeapByteBuffer extends ByteBuffer {
...省略...
HeapByteBuffer(int cap, int lim, MemorySegmentProxy segment) {// package-private
super(-1, 0, lim, cap, new byte[cap], 0, segment);//非直接缓冲区实质是一个数组
/*
hb = new byte[cap];
offset = 0;
*/
this.address = ARRAY_BASE_OFFSET;
}
...省略...
}
原理:
说明:
1、读取:当Java应用程序读取文件时,磁盘文件数据先读取到操作系统内存,再拷贝到非直接缓冲区,然后才能被应用程序读取;
2、写入:当Java应用程序向文件写入时,首先将数据写入非直接缓冲区,再写入操作系统内存,然后才能写入到磁盘文件;
allocateDirect(int capacity):
作用:创建指定大小的直接缓冲区对象,该缓冲区直接建立在物理内存中,即物理内存映射文件,应用程序直接操作物理内存映射文件,这样减少了中间copy过程,极大得提高了读写效率
源码:
package java.nio;
...省略...
public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer>{
...省略...
public static ByteBuffer allocateDirect(int capacity) {
return new DirectByteBuffer(capacity);
}
...省略...
}
package java.nio;
...省略...
class DirectByteBuffer extends MappedByteBuffer implements DirectBuffer{
...省略...
DirectByteBuffer(int cap) { // package-private
super(-1, 0, cap, cap, null);
boolean pa = VM.isDirectMemoryPageAligned();
int ps = Bits.pageSize();
long size = Math.max(1L, (long)cap + (pa ? ps : 0));
Bits.reserveMemory(size, cap);
long base = 0;
try {
base = UNSAFE.allocateMemory(size);
} catch (OutOfMemoryError x) {
Bits.unreserveMemory(size, cap);
throw x;
}
UNSAFE.setMemory(base, size, (byte) 0);
if (pa && (base % ps != 0)) {
// Round up to page boundary
address = base + ps - (base & (ps - 1));
} else {
address = base;
}
cleaner = Cleaner.create(this, new Deallocator(base, size, cap));
att = null;
}
...省略...
}
原理:
说明:
1、读取:当Java应用程序读取文件时,磁盘文件数据先读取到物理内存映射文件,然后应用程序直接从物理内存映射文件读取数据;
2、写入:当Java应用程序向文件写入时,首先将数据写入物理内存映射文件,然后操作系统直接将物理内存映射文件中数据写入到磁盘文件;
缺点:
1、非直接缓冲区由JVM分配,直接缓冲区由操作系统分配,直接缓冲区绕过了JVM堆栈,所以直接缓冲区创建和销毁比堆栈上的非直接缓冲区开销更大。
以上是关于非直接缓冲区与直接缓冲区的主要内容,如果未能解决你的问题,请参考以下文章