本文共 1452 字,大约阅读时间需要 4 分钟。
本文只是对两个buffer实现类做一个简单的总结,并没有深入的内容
byteBuffer创建时,两种类型
ByteBuffer buffer = ByteBuffer.allocate(10);
public static ByteBuffer allocate(int capacity) { if (capacity < 0) throw new IllegalArgumentException(); return new HeapByteBuffer(capacity, capacity); }
ByteBuffer buffer1 = ByteBuffer.allocateDirect(10);
public static ByteBuffer allocateDirect(int capacity) { return new DirectByteBuffer(capacity); }
这两种方法生成出来的对象都是保存在堆上的,不同的是,HeapByteBuffer中保存的数组对象,也是存储在堆内,而DirectByteBuffer中的数组对象占用的是堆外内存,
HeapByteBuffer在进行IO操作是,会把IO设备中的内容先读取到磁盘上,然后再从磁盘上读取到堆内(间接缓冲区)
DirectByteBuffer是直接将文件内容,从IO设备中,读取到程序中来,所以性能上会比较高(直接缓冲区)
直接缓冲区是在标准垃圾回收范围之外的,换言之,就是直接缓冲区,不会被垃圾回收清理到,一下是创建DirectByteBuffer内容
DirectByteBuffer(int cap) { // package-private super(-1, 0, cap, cap); 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; }
关于这部分的底层实现是未开源的,但是在buffer父类当中,address属性上面的注释,
将这个属性提升到这里,为了加速JNI 获取directByteBuffer的地址
--------------------------------------------------------
如有错误欢迎指正~
转载地址:http://wovti.baihongyu.com/