堆内存与直接内存的比较

2019-08-11  本文已影响0人  lenny611

除了常说的虚拟机运行时数据区以外,还有一部分内存也被频繁使用,他不是运行时数据区的一部分,也不是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的值来测试。

上一篇下一篇

猜你喜欢

热点阅读