美文网首页
NIO中FileChannel和MappedByteBuffer

NIO中FileChannel和MappedByteBuffer

作者: 陈阳001 | 来源:发表于2019-11-10 19:48 被阅读0次

    MappedByteBuffer实现MMAP(Memory Mapped Files)技术(内存映射)

    mmap(Memory Mapped Files),简单描述其作用就是:将磁盘文件映射到内存, 用户通过修改内存就能修改磁盘文件。
    它的工作原理是直接利用操作系统的Page来实现文件到物理内存的直接映射。完成映射之后你对物理内存的操作会被同步到硬盘上(操作系统在适当的时候)。
    通过mmap,进程像读写硬盘一样读写内存(当然是虚拟机内存),也不必关心内存的大小有虚拟内存为我们兜底。使用这种方式可以获取很大的I/O提升,省去了用户空间到内核空间复制的开销。
    mmap也有一个很明显的缺陷——不可靠,写到mmap中的数据并没有被真正的写到硬盘,操作系统会在程序主动调用flush的时候才把数据真正的写到硬盘。

    benchmark比较:

    小数据量测试,每次32byte

    FileChannel的性能

    /*
     @author:   chenyang
     @date  2019/11/10 12:10 AM
    
    */
    
    import java.io.RandomAccessFile;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;
    
    public class NormalNio {
    
        RandomAccessFile aFile;
    
        FileChannel inChannel;
    
        public NormalNio() throws Exception{
            this.aFile = new RandomAccessFile("/Users/chenyang/data/nio-data.txt", "rw");
            this.inChannel = aFile.getChannel();
            
        }
    
        public static void main(String[] args) throws Exception{
            NormalNio normalNio=new NormalNio();
    
            long start= System.currentTimeMillis();
            for(int k=0;k<100;k++) {//100*1024*1024=100m
                System.out.println(k);
                for (int i = 0; i < 1024; i++) {//1024*1024=1m
                    for (int j = 0; j < 32; j++) {//1024
                        normalNio.writeFile();
                    }
                }
            }
            System.out.println("执行时间:"+(System.currentTimeMillis()-start)/1000);
            normalNio.inChannel.close();
        }
    
    
        private void writeFile() throws Exception{
            inChannel.position(aFile.length());
            String newData = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ;
            byte[] bytes=newData.getBytes();
            ByteBuffer buf = ByteBuffer.allocate(48);
            buf.put(bytes);
            buf.flip();
            while (buf.hasRemaining()) {
                inChannel.write(buf);
            }
        }
    }
    

    响应时间:25s

    MappedByteBuffer(MMAP)的性能:

    import java.io.RandomAccessFile;
    import java.nio.MappedByteBuffer;
    import java.nio.channels.FileChannel;
    
    public class MappedByteBufferNio {
    
        RandomAccessFile aFile;
    
        FileChannel inChannel;
    
        MappedByteBuffer mappedByteBuffer;
    
        public MappedByteBufferNio() throws Exception{
            this.aFile = new RandomAccessFile("/Users/chenyang/data/nio-data.txt", "rw");
            this.inChannel = aFile.getChannel();
            //将文件的前 100*1024*1024 个字节映射到内存中
            this.mappedByteBuffer=inChannel.map(FileChannel.MapMode.READ_WRITE,0,100*1024*1024);
        }
    
        public static void main(String[] args) throws Exception{
            MappedByteBufferNio mappedByteBufferNio=new MappedByteBufferNio();
    
            long start= System.currentTimeMillis();
            for(int k=0;k<100;k++) {//100*1024*1024=100m
                System.out.println(k);
                for (int i = 0; i < 1024; i++) {//1024*1024=1m
                    for (int j = 0; j < 32; j++) {//1024
                        mappedByteBufferNio.writeFile();
                    }
                }
            }
            System.out.println("执行时间:"+(System.currentTimeMillis()-start)/1000);
            mappedByteBufferNio.inChannel.close();
            mappedByteBufferNio.aFile.close();
        }
    
    
        private void writeFile() throws Exception{
            inChannel.position(aFile.length());
            String newData = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ;//32 byte
            byte[] bytes=newData.getBytes();
            mappedByteBuffer.put(bytes);
    
        }
    }
    

    响应时间:6s

    相关文章

      网友评论

          本文标题:NIO中FileChannel和MappedByteBuffer

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