直接内存(Direct Memory)牛刀小试

[亡魂溺海] 提交于 2020-01-28 04:56:51

Direct Memory

特点

  • 常见于NIO操作时,用于数据缓存
  • 分配回收成本较高,但是读写性能高
  • 不受JVM内存回收管理

案例说明

为了做对比,还是直接写一段程序测试:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * 直接内存的读写测试
 */
public class Jvm1_9 {
    static final String fromFile="/tmp/12GB.dat";
    static final String toFile="/tmp/12GB_new.dat";
    //mkfile -n 12g  /tmp/12GB.dat
    static  final int _256M =256*1024*1024;
    public static void main(String[] args) {
        io();
        directBuffer();
    }
    public static  void ready(String file){
        File   f=new File(file);
        if(f.exists()){
            f.delete();
        }
    }
    public static void io(){
        ready(toFile);
        long start=System.nanoTime();
        try(FileInputStream from =new FileInputStream(fromFile);
            FileOutputStream to=new FileOutputStream((toFile));
        ){
           byte[] buffer=new  byte[_256M];
           while (true){
               int len=from.read(buffer);
              if(len==-1){
                  break;
              }
              to.write(buffer);
           }
        }catch (IOException e){
            e.printStackTrace();
        }
        long end=System.nanoTime();
        System.out.println("io耗时:"+(end-start)/1000_000.0);
    }
    public static void directBuffer(){
        ready(toFile);
        long start=System.nanoTime();
        try(FileChannel from =new FileInputStream(fromFile).getChannel();
            FileChannel to=new FileOutputStream((toFile)).getChannel();
            ){
            ByteBuffer byteBuffer=ByteBuffer.allocateDirect(_256M);
            while (true){
                int len=from.read(byteBuffer);
                if(len==-1){
                    break;
                }
                byteBuffer.flip();
                to.write(byteBuffer);
                byteBuffer.clear();
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        long end=System.nanoTime();
        System.out.println("directBuffer耗时:"+(end-start)/1000_000.0);
    }
}

程序说明:
分别使用传统的IO操作和使用direct操作进行对比,分配一样大小的buffer进行操作,然后做耗时对比。运行之前需要创建一个比较大的文件:

mkfile -n 12g  /tmp/12GB.dat

运行结果如下:

io耗时:38111.937769
directBuffer耗时:21497.436392

我们可以看到directbuffer有明显的提升,不过需要说明的是这个操作需要不断测试,而且文件的大小需要上量级,一开始我用来几M文件做测试,效果其实差别不大,主要是两种操作都比较快,不能说明问题。当文件数量达到一定规模之后,这种差异逐渐会稳定下来。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!