Java中的Heap Buffer与Direct Buffer

在使用Java NIO时,会常常和ByteBuffer打交道(吐槽下,每次手动flip切换读写模式太不友好)。在空Buffer建立时,有两种方式:java

ByteBuffer.allocateDirect(capacity)
ByteBuffer.allocate(capacity)

那么这两种Buffer的分配又有什么不同呢?数组

Heap Buffer

字面意思,在java heap上分配的内存。此块内存区域受JVM管理,GC负责回收。使用时无需担忧Heap Buffer的回收问题。app

Direct Buffer

堆外内存(说非堆不太准确,毕竟非堆区域不止这一块),时分配在C Heap上的Buffer,因为不属于JVM HEAP,管理/监控起来会比较困难,但也会被GC回收。DirectByteBuffer 自身是(Java)堆内的,它背后真正承载数据的buffer是在(Java)堆外——native memory中的。这是 malloc() 分配出来的内存,是用户态的。dom

那么为何有了Heap Buffer还须要Direct Buffer呢?工具

在JVM的垃圾回收器里,除了CMS,都是须要移动对象的;若是要把一个Java里的 byte[] 对象的引用传给native代码,让native代码直接访问数组的内容的话,就必需要保证native代码在访问的时候这个 byte[] 对象不能被移动,也就是要被“pin”(钉)住。spa

因而就出现了Direct Buffer,Direct Buffer是在C Heap中分配的内存,不像JVM堆内存是逻辑的,虽然也会被GC管理,但他是经过PhantomReference来达到的,正常的young gc或者mark and compact的时候不会在内存里移动。例如使用在传输数据时(磁盘IO传输和Socket传输都属于fd),若是传入HeapByteBuffer,首先会把HeapByteBuffer 背后的 byte[] 的内容拷贝到一个 DirectByteBuffer,而后再发送DirectByteBuffer中的数据。若是直接使用DirectByteBuffer的话,就会少了一次HeapByteBuffer->DirectByteBuffer的拷贝。插件

可是使用DirectByteBuffer也是有代价的,DirectByteBuffer比HeapByteBuffer的建立开销更大,因此若是要使用DirectByteBuffer的话最好仍是复用,避免过多的建立。code

堆外内存的监控

堆外内存不像堆内内存监控那么简单,不能直接看堆信息,但能够经过程序获取,或者经过一些监控工具来查看orm

jconsole

JCONSOLE监控堆外

jvisualvm

jvisualvm
注:须要安装VisualVM-BufferMonitor和VisualVM-MBeans插件对象

Java

ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4096);
        RandomAccessFile rw = new RandomAccessFile(new File("/Users/jiangxin/Desktop/111"), "rw");
        MappedByteBuffer map = rw.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 4097);

//打印堆外
List<BufferPoolMXBean> pools = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);
        for (BufferPoolMXBean pool : pools) {
            System.out.println(pool.getName());
            System.out.println(pool.getCount());
            System.out.println("memory used " + pool.getMemoryUsed());
            System.out.println("total capacity" + pool.getTotalCapacity());
            System.out.println();
        }
//print 
direct
1
memory used 4096
total capacity4096

mapped
1
memory used 4097
total capacity4097
相关文章
相关标签/搜索