磁盘io工作机制
1、标准方式
物理磁盘<-->内核空间<-->用户地址空间
2、直接I/O
物理磁盘<-->用户地址空间
数据库是这么干的,从同样是系统软件的角度来看,数据库是跟操作系统平起平坐的。
3、内存映射
物理磁盘<-->内核空间===用户地址空间
2跟3没有真正理解其区别,网上也没找到资料。
性能比较:代码来源ThinKing in java
1 package pers.jing.io; 2 3 import java.io.*; 4 import java.nio.IntBuffer; 5 import java.nio.channels.FileChannel; 6 7 public class MappedIO { 8 public static final int numberOfInts = 4000000; 9 public static final int numberOfUbuffInts = 2000000; 10 11 private abstract static class Tester { 12 private String name; 13 14 public Tester(String name) { 15 this.name = name; 16 } 17 18 public void runTest() { 19 System.out.print(name + ": "); 20 try { 21 long start = System.nanoTime(); 22 test(); 23 double duration = System.nanoTime() - start; 24 System.out.format("%.2f\n", duration / 1.0e9); 25 } catch (IOException e) { 26 throw new RuntimeException(e); 27 } 28 } 29 30 protected abstract void test() throws IOException; 31 } 32 33 private static Tester[] testers = { 34 new Tester("Stream Write") { 35 @Override 36 protected void test() throws IOException { 37 DataOutputStream dos = new DataOutputStream( 38 new BufferedOutputStream( 39 new FileOutputStream("temp.temp"))); 40 for (int i = 0; i < numberOfInts; i++) { 41 dos.writeInt(i); 42 } 43 dos.close(); 44 } 45 }, 46 new Tester("Mapped Write") { 47 @Override 48 protected void test() throws IOException { 49 FileChannel fc = new RandomAccessFile("temp.temp", "rw") 50 .getChannel(); 51 IntBuffer ib = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size()) 52 .asIntBuffer(); 53 for (int i = 0; i < numberOfInts; i++) { 54 ib.put(i); 55 } 56 ib.clear(); 57 } 58 }, 59 new Tester("Stream Read") { 60 @Override 61 protected void test() throws IOException { 62 DataInputStream dis = new DataInputStream( 63 new BufferedInputStream( 64 new FileInputStream("temp.temp"))); 65 for (int i = 0; i < numberOfInts; i++) { 66 dis.readInt(); 67 } 68 dis.close(); 69 } 70 }, 71 new Tester("Mapped Read") { 72 @Override 73 protected void test() throws IOException { 74 FileChannel fc = new RandomAccessFile("temp.temp", "rw") 75 .getChannel(); 76 IntBuffer ib = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size()) 77 .asIntBuffer(); 78 while (ib.hasRemaining()) { 79 ib.get(); 80 } 81 ib.clear(); 82 } 83 }, 84 new Tester("Stream rw") { 85 @Override 86 protected void test() throws IOException { 87 RandomAccessFile raf = new RandomAccessFile("temp.temp", "rw"); 88 raf.writeInt(1); 89 for (int i = 0; i < numberOfUbuffInts; i++) { 90 raf.seek(raf.length() - 4); 91 raf.writeInt(raf.readInt()); 92 } 93 raf.close(); 94 } 95 }, 96 new Tester("Mapped rw") { 97 @Override 98 protected void test() throws IOException { 99 FileChannel fc = new RandomAccessFile("temp.temp", "rw")100 .getChannel();101 IntBuffer ib = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size())102 .asIntBuffer();103 ib.put(0);104 for (int i = 1; i < numberOfUbuffInts; i++) {105 ib.put(ib.get(i - 1));106 }107 fc.close();108 }109 }110 };111 112 public static void main(String[] args) {113 for (Tester tester : testers) {114 tester.runTest();115 }116 }117 }