經過html
static ByteBuffer allocate(int capacity)
建立的緩衝區,在JVM中內存中建立,在每次調用基礎操做系統的一個本機IO以前或者以後,虛擬機都會將緩衝區的內容複製到中間緩衝區(或者從中間緩衝區複製內容),緩衝區的內容駐留在JVM內,所以銷燬容易,可是佔用JVM內存開銷,處理過程當中有複製操做。java
2)寫入步驟數組
1.建立一個臨時的直接ByteBuffer對象。
2.將非直接緩衝區的內容複製到臨時緩衝中。
3.使用臨時緩衝區執行低層次I/O操做。
4.臨時緩衝區對象離開做用域,並最終成爲被回收的無用數據。app
經過jvm
static ByteBuffer allocateDirect(int capacity)
建立的緩衝區,在JVM內存外開闢內存,在每次調用基礎操做系統的一個本機IO以前或者以後,虛擬機都會避免將緩衝區的內容複製到中間緩衝區(或者從中間緩衝區複製內容),緩衝區的內容駐留在物理內存內,會少一次複製過程,若是須要循環使用緩衝區,用直接緩衝區能夠很大地提升性能。雖然直接緩衝區使JVM能夠進行高效的I/O操做,但它使用的內存是操做系統分配的,繞過了JVM堆棧,創建和銷燬比堆棧上的緩衝區要更大的開銷。性能
直接緩衝區:內核地址空間和用戶地址空間之間造成了一個物理內存映射文件,減小了之間的copy過程。spa
這邊能夠看下jvm結構裏的直接內存:JVM虛擬機(一):java虛擬機的基本結構操作系統
1 package com.expgiga.NIO; 2 3 import java.nio.ByteBuffer; 4 5 /** 6 * 1、緩衝區(Buffer):在Java NIO中負責數據的存取,緩衝區就是數組,用於存儲不一樣數據類型的數據。 7 * 根據數據類型不一樣(boolean除外),提供了相應類型的緩衝區 8 * 9 * ByteBuffer 10 * CharBuffer 11 * ShortBuffer 12 * IntBuffer 13 * LongBuffer 14 * FloatBuffer 15 * DoubleBuffer 16 * 17 * 這些緩衝區的管理方式幾乎一致,經過allocate()獲取緩衝區。 18 * 19 * 2、緩衝區存取數據的兩個核心的方法: 20 * put() 存入數據到緩衝區 21 * get() 獲取緩衝區的數據 22 * 23 * 3、緩衝區中的四個核心屬性: 24 * capacity:容量,表示緩衝區中最大的存儲數據的容量,一旦聲明不能改變 25 * limit:界限,表示緩衝區中能夠操做數據的大小。(limit後數據不能進行讀寫) 26 * position:位置,表示緩衝區中正在操做數據的位置。 27 * 0 <= mark <= position <= limit <= capacity 28 * mark:標記,表示記錄當前position的位置,經過reset()恢復到mark的位置 29 * 30 * 4、直接緩衝區和非直接緩衝區 31 * 非直接緩衝區:經過allocate()分配緩衝區,將緩衝區創建在JVM的內存中 32 * 直接緩衝區:經過allocateDirect()分配直接緩衝區,將緩衝區創建在物理內存中,能夠提升效率。 33 */ 34 public class TestBuffer { 35 36 public static void main(String[] args) { 37 38 String str = "abcde"; 39 40 //1.分配一個指定大小的緩衝區 41 ByteBuffer buf = ByteBuffer.allocate(1024); 42 43 System.out.println("-----------allocate()----------"); 44 System.out.println(buf.position()); 45 System.out.println(buf.limit()); 46 System.out.println(buf.capacity());//0 1024 1024 47 48 //2.利用put()存入數據到緩衝區 49 buf.put(str.getBytes()); 50 System.out.println("-----------put()----------"); 51 System.out.println(buf.position()); 52 System.out.println(buf.limit()); 53 System.out.println(buf.capacity()); //5 1024 1024 54 55 //3.利用flip()切換成讀數據模式 56 buf.flip(); 57 System.out.println("-----------flip()----------"); 58 System.out.println(buf.position()); 59 System.out.println(buf.limit()); 60 System.out.println(buf.capacity()); //0 5 1024 61 62 //4.利用get()讀取緩衝區中的數據 63 byte[] dst = new byte[buf.limit()]; 64 buf.get(dst); 65 System.out.println(new String(dst, 0, dst.length)); 66 System.out.println("-----------get()----------"); 67 System.out.println(buf.position()); 68 System.out.println(buf.limit()); 69 System.out.println(buf.capacity()); //5 5 1024 70 71 //5.rewind()可重複讀數據 72 buf.rewind(); 73 System.out.println("-----------rewind()----------"); 74 System.out.println(buf.position()); 75 System.out.println(buf.limit()); 76 System.out.println(buf.capacity()); //0 5 1024 77 78 //6.清空緩衝區,可是緩衝區裏面的數據依然存在,數據存在被遺忘狀態 79 buf.clear(); 80 System.out.println("-----------clear()----------"); 81 System.out.println(buf.position()); 82 System.out.println(buf.limit()); 83 System.out.println(buf.capacity()); //0 1024 1024 84 85 System.out.println((char)buf.get());//a 86 87 88 //-------------------------------------------------------------- 89 String str2 = "abcde"; 90 ByteBuffer buf2 = ByteBuffer.allocate(1024); 91 buf2.put(str2.getBytes()); 92 93 buf2.flip(); 94 95 byte[] dst2 = new byte[buf.limit()]; 96 buf2.get(dst2, 0, 2); 97 98 System.out.println(new String(dst2, 0, 2)); 99 System.out.println(buf2.position());//2 100 101 //mark() 標記 102 buf2.mark(); 103 104 buf2.get(dst2, 2, 2); 105 System.out.println(new String(dst2, 2, 2)); 106 System.out.println(buf2.position());//4 107 108 //reset()恢復到mark的位置 109 buf2.reset(); 110 System.out.println(buf2.position());//2 111 112 //-------------------------------------------------------------- 113 //分配直接緩衝區 114 ByteBuffer buffer = ByteBuffer.allocateDirect(1024); 115 System.out.println(buffer.isDirect()); //判斷是不是直接緩衝區 116 } 117 }