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文件做测试,效果其实差别不大,主要是两种操作都比较快,不能说明问题。当文件数量达到一定规模之后,这种差异逐渐会稳定下来