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

堆内存与直接内存的比较

作者: 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的值来测试。

相关文章

  • 堆内存与直接内存的比较

    除了常说的虚拟机运行时数据区以外,还有一部分内存也被频繁使用,他不是运行时数据区的一部分,也不是Java虚拟机规范...

  • Netty-内存管理

    但是内存拷贝对性能有可能影响比较大,所以Java中可以绕开堆内存直接操作堆外内存,问题是创建堆外内存的速度比堆内存...

  • 直接内存与 JVM 源码分析

    直接内存(堆外内存) 直接内存有一种叫法,堆外内存。 直接内存(堆外内存)指的是 Java 应用程序通过直接方式从...

  • JVM学习(4)非堆的配置参数

    除了堆内存以外,虚拟机还有一些内存用于方法区,线程栈和直接内存的使用。它们与堆内存是独立的。虽然和堆内存相比,这些...

  • [转载] Java直接内存与堆内存

    本文转载自 http://blogxin.cn/2017/01/31/mappedbytebuffer-zeroc...

  • java直接内存

    直接内存 很多一说起直接内存,就会想到堆外内存。但是从概念上说,两者确实不是一回事。堆外内存,就是堆以外的内存,我...

  • java直接内存

    直接内存 很多一说起直接内存,就会想到堆外内存。但是从概念上说,两者确实不是一回事。堆外内存,就是堆以外的内存,我...

  • Java内存结构和垃圾回收

    内存结构 java内存结构主要有三大区块:栈内存,堆内存,堆外内存(直接内存)。其中: 1.栈内存主要是存放线程的...

  • Java 工程师成神之路(2018 年修订版)

    基础篇 1.1 JVM JVM内存结构 堆、栈、方法区、直接内存、堆和栈区别。 Java内存模型 内存可见性、重排...

  • Java程序员需要掌握的技能

    一、基础篇 1.JVM JVM内存结构 堆、栈、方法区、直接内存、堆和栈区别 Java内存模型 内存可见性...

网友评论

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

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