java mmap是什么,讓我們一起了解一下?
mmap是將一個(gè)文件或者其它對(duì)象映射進(jìn)內(nèi)存,文件被映射到多個(gè)頁(yè)上,如果文件的大小不是所有頁(yè)的大小之和,最后一個(gè)頁(yè)不被使用的空間將會(huì)清零。mmap在用戶空間映射調(diào)用系統(tǒng)中作用很大。
目前Java提供的mmap只有內(nèi)存文件映射,其他IO操作還沒(méi)有內(nèi)存映射功能。
Java內(nèi)存映射文件(Memory Mapped Files)就已經(jīng)在java.nio包中,但它對(duì)很多程序開(kāi)發(fā)者來(lái)說(shuō)仍然是一個(gè)相當(dāng)新的概念。引入NIO后,Java IO已經(jīng)相當(dāng)快,而且內(nèi)存映射文件提供了Java有可能達(dá)到的最快IO操作,這也是為什么那些高性能Java應(yīng)用應(yīng)該使用內(nèi)存映射文件來(lái)持久化數(shù)據(jù)。
mmap在Java中的用途是什么?
1、對(duì)普通文件使用mmap提供內(nèi)存映射I/O,以避免系統(tǒng)調(diào)用(read、write、lseek)帶來(lái)的性能開(kāi)銷。同時(shí)減少了數(shù)據(jù)在內(nèi)核緩沖區(qū)和進(jìn)程地址空間的拷貝次數(shù)。
2、使用特殊文件提供匿名內(nèi)存映射。
3、使用shm_open以提供無(wú)親緣關(guān)系進(jìn)程間的Posix共享內(nèi)存區(qū)。
mmap在Java中是如何使用的?(具體參考kafka源碼中的OffsetIndex這個(gè)類)
操作文件,就相當(dāng)于操作一個(gè)ByteBuffer一樣。
public?class?TestMmap?{undefined public?static?String?path?=?"C:\\Users\\64371\\Desktop\\mmap"; public?static?void?main(String[]?args)?throws?IOException?{undefined File?file1?=?new?File(path,?"1"); RandomAccessFile?randomAccessFile?=?new?RandomAccessFile(file1,?"rw"); int?len?=?2048; //?映射為2kb,那么生成的文件也是2kb MappedByteBuffer?mmap?=?randomAccessFile.getChannel().map(FileChannel.MapMode.READ_WRITE,?0,?len); System.out.println(mmap.isReadOnly()); System.out.println(mmap.position()); System.out.println(mmap.limit()); //?寫數(shù)據(jù)之后,JVM?退出之后會(huì)強(qiáng)制刷新的 mmap.put("a".getBytes()); mmap.put("b".getBytes()); mmap.put("c".getBytes()); mmap.put("d".getBytes()); //?System.out.println(mmap.position()); //?System.out.println(mmap.limit()); // //?mmap.force(); //?參考OffsetIndex強(qiáng)制回收已經(jīng)分配的mmap,不必等到下次GC, unmap(mmap); //?在Windows上需要執(zhí)行unmap(mmap);?否則報(bào)錯(cuò) //?Windows?won't?let?us?modify?the?file?length?while?the?file?is?mmapped //?java.io.IOException:?請(qǐng)求的操作無(wú)法在使用用戶映射區(qū)域打開(kāi)的文件上執(zhí)行 randomAccessFile.setLength(len/2); mmap?=?randomAccessFile.getChannel().map(FileChannel.MapMode.READ_WRITE,?0,?len/2); //?A?mapping,?once?established,?is?not?dependent?upon?the?file?channel //?that?was?used?to?create?it.?Closing?the?channel,?in?particular,?has?no //?effect?upon?the?validity?of?the?mapping. randomAccessFile.close(); mmap.put(128,?"z".getBytes()[0]); } //?copy?from?FileChannelImpl#unmap(私有方法) private?static?void?unmap(MappedByteBuffer?bb)?{undefined Cleaner?cl?=?((DirectBuffer)bb).cleaner(); if?(cl?!=?null) cl.clean(); } }
以上就是小編今天的分享了,希望可以幫助到大家。