資料開發_Java中記憶體對映檔案
阿新 • • 發佈:2020-11-24
記憶體對映檔案
1.FileChannel 和外界的介質進行互動 有3種模式:READ_ONLY(只讀)、READ_WRITE(讀寫)、PRIVATE(私有,用於copy-on-write) 1.MappedByteBuffer一旦建立,就與建立它的通道無關,即通道關閉時,不影響該緩衝器 FileChannel channel = FileChannel.open(path,options); 2. MappedByteBuffer map 2.緩衝區的操作 緩衝區的操作可以檢視Java API java.nio.Buffer 3.加鎖 多個執行緒訪問的情況下考慮
memory-map files
Java Memory-Mapped File所使用的記憶體分配在實體記憶體而不是JVM堆記憶體,且分配在OS核心 在一般的檔案讀寫中,會有兩次資料拷貝,一次是從硬碟拷貝到作業系統核心,另一次是從作業系統核心拷貝到使用者態的應用程式。 而在記憶體對映檔案中,一般情況下,只有一次拷貝,且記憶體分配在作業系統核心,應用程式訪問的就是作業系統的核心記憶體空間。 Java語言通過java.nio包支援記憶體對映檔案和IO 對於一般的檔案讀寫不需要使用記憶體對映檔案, 但如果處理的是大檔案,要求極高的讀寫效率, 比如資料庫系統或繁忙的電子交易系統, 或者需要在不同程式間進行共享和通訊,那就可以考慮記憶體對映檔案 讀寫記憶體對映檔案是作業系統來負責的,因此,即使你的Java程式在寫入記憶體後就掛掉了,只要作業系統工作正常,資料就會寫入磁碟 Direct位元組快取比non-direct位元組快取效能要好
程式碼示例
import java.nio.ByteBuffer; public class ByteBufferExp { public static void main(String args[]) { // 啟動JAVA虛擬機器時使用引數-Xmx100m Runtime run = Runtime.getRuntime(); System.out.println("最大記憶體MB = " + run.maxMemory()/1024/1024); System.out.println("已分配記憶體 = " + run.totalMemory()/1024/1024); System.out.println("已分配記憶體中的剩餘空間 = " + run.freeMemory()/1024/1024); System.out.println("已分配記憶體中的使用空間 = " + (run.totalMemory() -run.freeMemory())/1024/1024 ); System.out.println("剩餘最大可用於 記憶體 = " + (run.maxMemory()+ run.freeMemory()-run.totalMemory())/1024/1024); System.out.println("----------allocate--------"); //4個靜態工廠方法來獲得ByteBuffer的例項 System.out.println("before alocate 即已分配記憶體中的剩餘空間:" + run.freeMemory()/1024/1024); // 從 堆空間 中分配一個容量大小為capacity的byte陣列作為緩衝區的byte資料儲存器 //將建立一個容量為 26位元組的ByteBuffer,如果發現建立的緩衝區容量太小,唯一的選擇就是重新建立一個大小合適的緩衝區. ByteBuffer buffer = ByteBuffer.allocate(26*1024*1024); // 緩衝區都有4個屬性:capacity、limit、position // capacity 容量,即可以容納的最大資料量;在緩衝區建立時被設定並且不能改變 System.out.println("緩衝區 buffer = " + buffer); System.out.println("緩衝區alocate 之後:" + run.freeMemory()/1024/1024); //通過作業系統來建立記憶體塊用作緩衝區 這部分直接用的系統記憶體,所以對JVM的記憶體沒有影響 ByteBuffer directBuffer = ByteBuffer.allocateDirect(100*1024*1024); System.out.println("直接緩衝區 directBuffer = " + directBuffer); System.out.println(" 直接緩衝區 direct alocate 之後:" + run.freeMemory()/1024/1024); System.out.println("----------Test wrap--------"); // 通過包裝的方法建立的緩衝區保留了被包裝陣列內儲存的資料 byte[] bytes = new byte[32]; buffer = ByteBuffer.wrap(bytes); System.out.println("緩衝區wrap buffer = " + buffer); System.out.println("wrap buffer 之後:" + run.freeMemory()/1024/1024); // 以指定偏移量和長度,這個offset也就是包裝後byteBuffer的position, // 而length呢就是limit-position的大小,從而我們可以得到limit的位置為length+position(offset) buffer = ByteBuffer.wrap(bytes, 10, 10); System.out.println("緩衝區wrap buffer = " + buffer); System.out.println("wrap buffer 之後:" + run.freeMemory()/1024/1024); } } A byte buffer,一個位元組緩衝區 Objects of this class may reside almost entirely in memory-map files. That is the primary reason for them to be considered immutable, since no reallocation is possible when using2020/11/20 memory-mapped files.