<link rel="stylesheet" href="https://js.how234.com/third-party/SyntaxHighlighter/shCoreDefault.css" type="text/css" /><script type="text/javascript" src="https://js.how234.com/third-party/SyntaxHighlighter/shCore.js"></script><script type="text/javascript"> SyntaxHighlighter.all(); </script>
java mmap是什麼,讓我們一起了解一下?
mmap是將一個檔案或者其它對象映射進內存,檔案被映射到多個頁上,如果檔案的大小不是所有頁的大小之和,最後一個頁不被使用的空間將會清零。mmap在用戶空間映射調用系統中作用很大。
目前Java提供的mmap只有內存檔案映射,其他IO操作還沒有內存映射功能。
Java內存映射檔案(Memory Mapped Files)就已經在java.nio包中,但它對很多程序開發者來說仍然是一個相當新的概念。引入NIO後,Java IO已經相當快,而且內存映射檔案提供了Java有可能達到的最快IO操作,這也是爲什麼那些高性能Java應用應該使用內存映射檔案來持久化數據。
mmap在Java中的用途是什麼?
1、對普通檔案使用mmap提供內存映射I/O,以避免系統調用(read、write、lseek)帶來的性能開銷。同時減少了數據在內核緩衝區和進程地址空間的拷貝次數。
2、使用特殊檔案提供匿名內存映射。
3、使用shm_open以提供無親緣關係進程間的posix共享內存區。
mmap在Java中是如何使用的?(具體參考kafka源碼中的OffsetIndex這個類)
操作檔案,就相當於操作一個ByteBuffer一樣。
public class TestMmap {undefinedpublic static String path = "C:Users64371Desktopmmap";public static void main(String[] args) throws IOException {undefinedFile file1 = new File(path, "1");RandomAccessFile randomAccessFile = new RandomAccessFile(file1, "rw");int len = 2048;// 映射爲2kb,那麼生成的檔案也是2kbMappedByteBuffer 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());// 寫數據之後,JVM 退出之後會強制重新載入的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強制回收已經分配的mmap,不必等到下次GC,unmap(mmap);// 在Windows上需要執行unmap(mmap); 否則報錯// Windows won't let us modify the file length while the file is mmapped// java.io.IOException: 請求的操作無法在使用用戶映射區域開啟的檔案上執行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) {undefinedCleaner cl = ((DirectBuffer)bb).cleaner();if (cl != null)cl.clean();}}