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