美文网首页
DirectBuffer

DirectBuffer

作者: 远o_O | 来源:发表于2017-07-22 17:02 被阅读54次

    DircetBuffer

    • directBuffer是和Java堆相区分的,更合适的是HeapBuffer,理论上DirectBuffer大小由操作系统可以给用户进程的内存大小所决定(虚拟内存,操作系统位数)。JVM提供了虚拟机参数可以配置直接内存的大小,理论上可以配置很大,但是和操作系统紧密相关。

    DirectBuffer优缺点

    • 堆外内存的申请与普通的Java对象是有巨大的差别的。在以后的课程里,大家会发现,Java对象在Java堆里申请内存的时候,实际上是比malloc要快的,所以DirectBuffer的创建效率往往是比Heap Buffer差的。

    • 但是,如果进行网络读写或者文件读写的时候,DirectBuffer就会比较快了,说起来好笑,这个快是因为JDK故意把非HeapBuffer的读写搞慢的,我们看一下JDK的源代码。

    static int write(FileDescriptor fd, ByteBuffer src, long position,
                         NativeDispatcher nd) 
            throws IOException
        {   
            if (src instanceof DirectBuffer)
                return writeFromNativeBuffer(fd, src, position, nd);
    
            // Substitute a native buffer
            int pos = src.position();
            int lim = src.limit();
            assert (pos <= lim);
            int rem = (pos <= lim ? lim - pos : 0); 
            ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
            try {
                bb.put(src);
                bb.flip();
    

    关键点在这个方法的第一行,如果src是DirectBuffer,就直接调用writeFromNativeBuffer,如果不是,则要先创建一个临时的DirectBuffer,把src拷进去,然后再调用真正的写操作。为什么要这么干呢?还是要从DirectBuffer不会被GC移动说起。

    writeFromNativeBuffer的实现,最终会把Buffer的address传给操作系统,让操作系统把address开始的那一段内存发送到网络上。这就要求在操作系统进行发送的时候,这块内存是不能动的。而我们知道,GC是会乱搬Java堆里的东西的,所以无奈,我们必须得弄一块地址不会变化的内存,然后把这个地址发给操作系统。

    DirectBuffer当然还有一个直观的优点,不被GC管理,所以发生GC的时候,整理内存的压力就会小。当然,我后面也会讲,它并不是完全不被GC管理,它还是能被回收的,但是在GC平常整理内存的时候确实是不会去管它的。

    相关文章

      网友评论

          本文标题:DirectBuffer

          本文链接:https://www.haomeiwen.com/subject/zdpukxtx.html