美文网首页
堆内存与直接内存的比较

堆内存与直接内存的比较

作者: lenny611 | 来源:发表于2019-08-11 14:05 被阅读0次

    除了常说的虚拟机运行时数据区以外,还有一部分内存也被频繁使用,他不是运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,就是直接内存。
    直接内存的分配不受Java堆大小的限制,但是他还是会收到服务器总内存的影响。
    在JDK 1.4中引入的NIO中,引入了一种基于Channel和Buffer的I/O方式,他可以使用Native函数直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的应用进行操作。如下图所示:


    直接内存.jpg

    代码测试如下:

    import java.nio.ByteBuffer;
    public class ByteBufferCompare {
        public static void main(String[] args) {
            allocateCompare();
            System.out.println("——————————————————————————————————" );
            operateCompare();
    
        }
         public static void  operateCompare(){
            //直接内存在直接的IO 操作上,在频繁的读写时 会有显著的性能提升
             int time=10000000;
             long startTime = System.currentTimeMillis();
             ByteBuffer buffer = ByteBuffer.allocate(2*time);
             read(time, buffer);
             long endTime= System.currentTimeMillis();;
             System.out.println("在进行"+time+"次读写操作时,非直接内存(堆)分配耗时:" + (endTime-startTime) +"ms" );
             long sTime = System.currentTimeMillis();
             ByteBuffer buffer2 = ByteBuffer.allocateDirect(2*time);
             read(time, buffer2);
             long eTime= System.currentTimeMillis();;
             System.out.println("在进行"+time+"次读写操作时,直接内存分配耗时:" + (eTime-sTime) +"ms" );
    
    
         }
    
        private static void read(int time, ByteBuffer buffer) {
            for (int i = 0; i <time; i++) {
                  buffer.putChar('a');
            }
            buffer.flip();//将缓存字节数组的指针设置为数组的开始序列即数组下标0。方便进行遍历(读取)
            for (int i = 0; i < time; i++) {
                buffer.getChar();
            }
        }
    
        public static void allocateCompare(){
            //直接内存分配比堆内存分配更慢
            int time=10000000;
            long startTime = System.currentTimeMillis();
            for (int i = 0; i <time; i++) {
                ByteBuffer buffer = ByteBuffer.allocate(2);
            }
            long endTime = System.currentTimeMillis();
            System.out.println("在进行"+time+"次分配操作时,非直接内存(堆)分配耗时:" + (endTime-startTime) +"ms" );
            long sTime = System.currentTimeMillis();
            for (int i = 0; i <time; i++) {
                ByteBuffer buffer = ByteBuffer.allocateDirect(2);
            }
            long eTime = System.currentTimeMillis();
            System.out.println("在进行"+time+"次分配操作时,直接内存分配耗时:" + (eTime-sTime) +"ms" );
    
        }
    }
    
    

    执行结果如下:


    运行结果图.png

    小结:
    在分配内存时,堆内存分配的速度明显比直接内存分配的速度快,尤其是数据量增大之后;
    而在频繁的IO操作时,按道理来说应该是直接内存更快,但是在这里答主的内存不够,再往上加就Java heap space,所以想要尝试的话可以自己修改time的值来测试。

    相关文章

      网友评论

          本文标题:堆内存与直接内存的比较

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