最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java Buffer緩沖區(qū)操作與內(nèi)存管理最佳實(shí)踐

 更新時(shí)間:2025年09月23日 10:00:48   作者:Yeats_Liao  
Java NIO的Buffer是數(shù)據(jù)容器,管理堆/堆外內(nèi)存,具備position、limit、capacity三大屬性,支持讀寫切換,直接緩沖區(qū)I/O快但創(chuàng)建較慢,非直接緩沖區(qū)更易管理,根據(jù)場(chǎng)景選擇合適類型以優(yōu)化性能,本文給大家介紹Java Buffer緩沖區(qū)操作與內(nèi)存管理最佳實(shí)踐,感興趣的朋友一起看看吧

Buffer緩沖區(qū)操作與內(nèi)存管理

1 Buffer的設(shè)計(jì)原理和內(nèi)存模型

1.1 Buffer到底是什么

Buffer就是Java NIO里的數(shù)據(jù)容器,專門用來存放各種基本類型的數(shù)據(jù)。你可以把它想象成一個(gè)智能的數(shù)組,不僅能存數(shù)據(jù),還知道自己當(dāng)前讀到哪了、寫到哪了。

和Channel配合使用時(shí),Buffer就像是數(shù)據(jù)的中轉(zhuǎn)站。Channel負(fù)責(zé)傳輸,Buffer負(fù)責(zé)存儲(chǔ),兩者分工明確。

Buffer有幾個(gè)設(shè)計(jì)特點(diǎn):

  1. 專一性:每種數(shù)據(jù)類型都有對(duì)應(yīng)的Buffer,比如ByteBuffer、IntBuffer
  2. 內(nèi)存靈活:可以用堆內(nèi)存,也可以用堆外內(nèi)存
  3. 狀態(tài)清晰:讀模式和寫模式分得很清楚
  4. 自動(dòng)跟蹤:會(huì)自動(dòng)記錄當(dāng)前操作的位置

1.2 Buffer家族成員

Java NIO的Buffer家族結(jié)構(gòu)很簡(jiǎn)單,就是一個(gè)抽象父類加上各種具體實(shí)現(xiàn):

Buffer (抽象類)
├── ByteBuffer          // 最常用的,處理字節(jié)數(shù)據(jù)
│   └── MappedByteBuffer    // 內(nèi)存映射文件專用
│       ├── DirectByteBuffer    // 直接內(nèi)存實(shí)現(xiàn)
│       └── FileChannelImpl.MappedByteBufferAdapter
├── CharBuffer          // 處理字符
├── DoubleBuffer        // 處理雙精度浮點(diǎn)數(shù)
├── FloatBuffer         // 處理單精度浮點(diǎn)數(shù)
├── IntBuffer           // 處理整數(shù)
├── LongBuffer          // 處理長(zhǎng)整數(shù)
└── ShortBuffer         // 處理短整數(shù)

ByteBuffer是老大,用得最多,因?yàn)榫W(wǎng)絡(luò)傳輸和文件操作基本都是字節(jié)流。MappedByteBuffer是個(gè)特殊的存在,專門用來做內(nèi)存映射文件,讀寫大文件時(shí)特別有用。

1.3 Buffer的內(nèi)存模型

Buffer的內(nèi)存可以從兩個(gè)角度來看:

1.3.1 邏輯上怎么理解

邏輯上,Buffer就是一個(gè)有序的數(shù)組,里面裝著同一種類型的數(shù)據(jù)。每個(gè)位置都有索引,你可以直接跳到任意位置讀寫數(shù)據(jù)。

Buffer用三個(gè)重要的指針來管理這個(gè)數(shù)組:position(當(dāng)前位置)、limit(邊界)和capacity(總?cè)萘浚?。這三個(gè)指針決定了你能在哪讀、在哪寫、總共有多大空間。

1.3.2 物理上怎么實(shí)現(xiàn)

物理實(shí)現(xiàn)上,Buffer有兩種存儲(chǔ)方式:

堆緩沖區(qū)(HeapBuffer)

  • 數(shù)據(jù)存在JVM堆內(nèi)存里
  • 底層就是個(gè)普通的Java數(shù)組
  • 會(huì)被垃圾回收器管理
  • 創(chuàng)建方式:ByteBuffer.allocate(1024)

直接緩沖區(qū)(DirectBuffer)

  • 數(shù)據(jù)存在操作系統(tǒng)的原生內(nèi)存里(堆外內(nèi)存)
  • 不占用JVM堆空間
  • 垃圾回收器管不著,需要手動(dòng)或等待回收
  • 創(chuàng)建方式:ByteBuffer.allocateDirect(1024)

還有個(gè)特殊的MappedByteBuffer,它把文件直接映射到內(nèi)存里,讀寫文件就像操作內(nèi)存一樣快。

2 position、limit、capacity三大屬性詳解

Buffer有三個(gè)關(guān)鍵屬性:position、limit和capacity。這三個(gè)屬性就像是Buffer的GPS,告訴你現(xiàn)在在哪、能到哪、總共有多大。

2.1 capacity(容量)

capacity就是Buffer的總?cè)萘浚瑒?chuàng)建時(shí)就定死了,后面改不了。就像買了個(gè)1024字節(jié)的水桶,不管你裝多少水,桶的容量就是1024。

  • 含義:Buffer最多能裝多少個(gè)元素
  • 特點(diǎn):一旦創(chuàng)建就固定了
  • 范圍:capacity ≥ 0
// 創(chuàng)建一個(gè)能裝1024個(gè)字節(jié)的Buffer
ByteBuffer buffer = ByteBuffer.allocate(1024);
int capacity = buffer.capacity(); // 返回1024,永遠(yuǎn)不變

2.2 position(位置)

position是個(gè)移動(dòng)的指針,指向下一個(gè)要操作的位置。每次讀寫數(shù)據(jù),這個(gè)指針就會(huì)自動(dòng)往前移。

  • 含義:下一個(gè)要讀或?qū)懙奈恢?/li>
  • 特點(diǎn):會(huì)隨著操作自動(dòng)移動(dòng)
  • 范圍:0 ≤ position ≤ limit

寫模式時(shí),position指向下一個(gè)要寫入的地方;讀模式時(shí),position指向下一個(gè)要讀取的地方。

ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.put((byte) 'A'); // position從0跳到1
buffer.put((byte) 'B'); // position從1跳到2
int currentPosition = buffer.position(); // 現(xiàn)在是2

2.3 limit(限制)

limit是個(gè)邊界線,告訴你最多能操作到哪里。超過這條線就不能讀寫了。

  • 含義:第一個(gè)不能碰的位置
  • 特點(diǎn):可以手動(dòng)調(diào)整
  • 范圍:position ≤ limit ≤ capacity

寫模式時(shí),limit就是capacity(能寫滿整個(gè)Buffer);讀模式時(shí),limit是之前寫了多少數(shù)據(jù)。

ByteBuffer buffer = ByteBuffer.allocate(10);
// 寫模式:limit = capacity = 10,可以寫滿
int limitInWriteMode = buffer.limit(); // 返回10
// 寫入3個(gè)字節(jié)后切換到讀模式
buffer.put((byte) 'A').put((byte) 'B').put((byte) 'C');
buffer.flip(); // 切換到讀模式
// 讀模式:limit = 3,只能讀這3個(gè)字節(jié)
int limitInReadMode = buffer.limit(); // 返回3

2.4 三個(gè)屬性的關(guān)系圖解

用一個(gè)例子來看看這三個(gè)屬性是怎么配合工作的:

// 創(chuàng)建一個(gè)能裝8個(gè)字節(jié)的Buffer
ByteBuffer buffer = ByteBuffer.allocate(8);
System.out.println("剛創(chuàng)建時(shí):");
System.out.println("capacity: " + buffer.capacity()); // 8,總?cè)萘?
System.out.println("limit: " + buffer.limit());       // 8,能寫到哪
System.out.println("position: " + buffer.position()); // 0,當(dāng)前位置
// 寫入數(shù)據(jù)
buffer.put("ABCD".getBytes());
System.out.println("\n寫入ABCD后:");
System.out.println("capacity: " + buffer.capacity()); // 8,總?cè)萘坎蛔?
System.out.println("limit: " + buffer.limit());       // 8,還能繼續(xù)寫
System.out.println("position: " + buffer.position()); // 4,指針移到第4位
// 切換到讀模式
buffer.flip();
System.out.println("\nflip()切換讀模式后:");
System.out.println("capacity: " + buffer.capacity()); // 8,總?cè)萘坎蛔?
System.out.println("limit: " + buffer.limit());       // 4,只能讀4個(gè)字節(jié)
System.out.println("position: " + buffer.position()); // 0,從頭開始讀

狀態(tài)變化圖示:

剛創(chuàng)建(寫模式):
[0][1][2][3][4][5][6][7]
 ^                       ^
position              limit/capacity
寫入ABCD后:
[A][B][C][D][ ][ ][ ][ ]
             ^           ^
          position   limit/capacity
flip()后(讀模式):
[A][B][C][D][ ][ ][ ][ ]
 ^           ^           ^
position   limit      capacity

2.5 mark(標(biāo)記)

mark就像是在Buffer上做個(gè)書簽,記住某個(gè)位置,以后可以快速跳回來。

  • 含義:臨時(shí)記住的位置
  • 特點(diǎn):可有可無,默認(rèn)沒有
  • 范圍:mark ≤ position
ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.put((byte) 'A');
buffer.put((byte) 'B');
buffer.mark(); // 在position=2的地方做個(gè)書簽
buffer.put((byte) 'C');
buffer.reset(); // 跳回書簽位置(position=2)

3 讀寫模式切換和常用操作方法

3.1 讀寫模式切換

Buffer就像一個(gè)雙向通道,可以往里寫數(shù)據(jù),也可以從里面讀數(shù)據(jù)。但不能同時(shí)進(jìn)行,需要在寫模式和讀模式之間切換。

3.1.1 flip():寫模式切換到讀模式
public final Buffer flip() {
    limit = position;     // 設(shè)置讀取邊界
    position = 0;         // 從頭開始讀
    mark = -1;           // 清除書簽
    return this;
}

flip()就像翻書一樣,做三件事:

  1. 把當(dāng)前寫到的位置設(shè)為讀取邊界(limit = position)
  2. 把讀取指針拉回到開頭(position = 0)
  3. 清除之前的書簽(mark = -1)

這樣就能從頭開始讀取剛才寫入的數(shù)據(jù)了。

3.1.2 clear():讀模式切換到寫模式
public final Buffer clear() {
    position = 0;         // 從頭開始寫
    limit = capacity;     // 可以寫滿整個(gè)Buffer
    mark = -1;           // 清除書簽
    return this;
}

clear()就像清空黑板重新寫字,做三件事:

  1. 把寫入指針拉回到開頭(position = 0)
  2. 允許寫滿整個(gè)Buffer(limit = capacity)
  3. 清除之前的書簽(mark = -1)

注意:clear()并不會(huì)真的清除數(shù)據(jù),只是重置了指針,舊數(shù)據(jù)會(huì)被新數(shù)據(jù)覆蓋。

3.1.3 compact():部分讀模式切換到寫模式
public ByteBuffer compact() {
    // 把沒讀完的數(shù)據(jù)移到前面
    System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
    position(remaining());  // position指向未讀數(shù)據(jù)后面
    limit(capacity());      // 可以寫滿整個(gè)Buffer
    discardMark();         // 清除書簽
    return this;
}

compact()比較聰明,它會(huì)保留沒讀完的數(shù)據(jù):

  1. 把沒讀完的數(shù)據(jù)移到Buffer開頭
  2. position指向這些數(shù)據(jù)的后面(可以繼續(xù)寫新數(shù)據(jù))
  3. limit設(shè)為capacity(允許寫滿)
  4. 清除書簽

這樣既保留了未讀數(shù)據(jù),又能繼續(xù)寫入新數(shù)據(jù)。

3.2 常用操作方法

3.2.1 分配Buffer
// 在JVM堆內(nèi)存里創(chuàng)建,速度快
ByteBuffer heapBuffer = ByteBuffer.allocate(1024);
// 在系統(tǒng)內(nèi)存里創(chuàng)建,I/O效率高
ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
// 把現(xiàn)有數(shù)組包裝成Buffer
byte[] array = new byte[1024];
ByteBuffer wrappedBuffer = ByteBuffer.wrap(array);
3.2.2 寫入數(shù)據(jù)
// 寫一個(gè)字節(jié),position自動(dòng)+1
buffer.put((byte) 127);
// 寫一串字節(jié)
byte[] data = "Hello".getBytes();
buffer.put(data);
// 在指定位置寫入,不影響position
buffer.put(3, (byte) 65); // 在第3個(gè)位置寫入'A'
// 從數(shù)組的某個(gè)位置開始,寫入指定長(zhǎng)度
buffer.put(data, 1, 3); // 從data[1]開始寫3個(gè)字節(jié)
3.2.3 讀取數(shù)據(jù)
// 讀一個(gè)字節(jié),position自動(dòng)+1
byte b = buffer.get();
// 讀一串字節(jié)到數(shù)組里
byte[] data = new byte[10];
buffer.get(data);
// 從指定位置讀取,不影響position
byte b = buffer.get(3); // 讀取第3個(gè)位置的字節(jié)
// 讀指定長(zhǎng)度到數(shù)組的某個(gè)位置
buffer.get(data, 1, 3); // 讀3個(gè)字節(jié)到data[1]開始的位置
3.2.4 其他常用操作
// 做書簽和跳回書簽
buffer.mark();  // 在當(dāng)前position做個(gè)書簽
buffer.reset(); // 跳回書簽位置
// 倒帶,position回到0
buffer.rewind();
// 檢查還能讀多少
boolean hasRemaining = buffer.hasRemaining(); // 還有數(shù)據(jù)嗎?
int remaining = buffer.remaining(); // 還剩多少個(gè)(limit - position)
// 手動(dòng)移動(dòng)position
buffer.position(buffer.position() + 3); // 跳過3個(gè)位置
// 復(fù)制Buffer,共享數(shù)據(jù)但各自有獨(dú)立的指針
ByteBuffer duplicate = buffer.duplicate();
// 創(chuàng)建只讀版本,不能修改數(shù)據(jù)
ByteBuffer readOnlyBuffer = buffer.asReadOnlyBuffer();
// 切片,共享一部分?jǐn)?shù)據(jù)
ByteBuffer slicedBuffer = buffer.slice(2, 5); // 從位置2開始,長(zhǎng)度5的片段

3.3 Buffer操作的最佳實(shí)踐

  1. 檢查返回值:讀寫操作可能沒有處理完所有數(shù)據(jù)
  2. 記得flip():寫完數(shù)據(jù)要調(diào)用flip()才能讀取
  3. 重復(fù)利用:用clear()或compact()重用Buffer,別老是new
  4. 選對(duì)類型:什么數(shù)據(jù)用什么Buffer(ByteBuffer、IntBuffer等)
  5. 直接緩沖區(qū)要小心:它不歸垃圾回收器管,用完要手動(dòng)釋放

4 直接緩沖區(qū)vs非直接緩沖區(qū)的性能差異

4.1 兩種緩沖區(qū)的實(shí)現(xiàn)機(jī)制

4.1.1 非直接緩沖區(qū)(HeapBuffer)

非直接緩沖區(qū)就是在JVM堆內(nèi)存里創(chuàng)建的Buffer,底層用的是普通Java數(shù)組。做I/O操作時(shí),JVM需要把數(shù)據(jù)在堆內(nèi)存和系統(tǒng)內(nèi)存之間復(fù)制一遍。

ByteBuffer heapBuffer = ByteBuffer.allocate(1024); // 在堆內(nèi)存里創(chuàng)建

內(nèi)部實(shí)現(xiàn)

// HeapByteBuffer的底層實(shí)現(xiàn)(簡(jiǎn)化版)
final byte[] hb;  // 就是個(gè)普通數(shù)組
final int offset; // 數(shù)組里的起始位置
// 讀取操作
public byte get() {
    return hb[ix(nextGetIndex())];
}
// 寫入操作
public ByteBuffer put(byte b) {
    hb[ix(nextPutIndex())] = b;
    return this;
}
4.1.2 直接緩沖區(qū)(DirectBuffer)

直接緩沖區(qū)是在系統(tǒng)內(nèi)存里創(chuàng)建的Buffer,不在JVM堆里。它通過JNI調(diào)用系統(tǒng)API分配內(nèi)存,Java通過Unsafe類來訪問這塊內(nèi)存。

ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024); // 在系統(tǒng)內(nèi)存里創(chuàng)建

內(nèi)部實(shí)現(xiàn)

// DirectByteBuffer的底層實(shí)現(xiàn)(簡(jiǎn)化版)
private long address; // 系統(tǒng)內(nèi)存地址
// 讀取操作
public byte get() {
    return Unsafe.getByte(ix(nextGetIndex())); // 直接從系統(tǒng)內(nèi)存讀
}
// 寫入操作
public ByteBuffer put(byte b) {
    Unsafe.putByte(ix(nextPutIndex()), b); // 直接寫到系統(tǒng)內(nèi)存
    return this;
}

4.2 性能差異分析

4.2.1 內(nèi)存分配性能
緩沖區(qū)類型分配速度釋放速度內(nèi)存壓力
非直接緩沖區(qū)GC自動(dòng)回收占用堆內(nèi)存
直接緩沖區(qū)慢(要調(diào)系統(tǒng)API)看GC臉色或手動(dòng)釋放不占堆內(nèi)存

直接緩沖區(qū)創(chuàng)建比較慢,因?yàn)橐{(diào)用系統(tǒng)API分配內(nèi)存。但一旦創(chuàng)建好了,做I/O操作時(shí)通常比非直接緩沖區(qū)快。

4.2.2 I/O操作性能
緩沖區(qū)類型讀寫性能數(shù)據(jù)復(fù)制適用場(chǎng)景
非直接緩沖區(qū)一般要在堆內(nèi)存和系統(tǒng)內(nèi)存間復(fù)制小數(shù)據(jù)、偶爾用用
直接緩沖區(qū)不用復(fù)制大數(shù)據(jù)、頻繁I/O

直接緩沖區(qū)做I/O時(shí)比較快,因?yàn)椴挥迷诙褍?nèi)存和系統(tǒng)內(nèi)存之間復(fù)制數(shù)據(jù)。用Channel傳輸數(shù)據(jù)時(shí),直接緩沖區(qū)可以直接參與,而非直接緩沖區(qū)還得先復(fù)制到一個(gè)臨時(shí)的直接緩沖區(qū)里。

4.2.3 內(nèi)存訪問性能
緩沖區(qū)類型讀寫速度CPU緩存友好性JVM優(yōu)化
非直接緩沖區(qū)一般更快JIT能優(yōu)化
直接緩沖區(qū)通過JNI訪問,可能慢點(diǎn)一般優(yōu)化有限

如果只是在Java代碼里頻繁讀寫B(tài)uffer,非直接緩沖區(qū)通常更快,因?yàn)樗贘VM堆里,JIT編譯器能優(yōu)化,對(duì)CPU緩存也更友好。

4.3 性能測(cè)試案例

來個(gè)實(shí)際測(cè)試,看看兩種Buffer在不同場(chǎng)景下的表現(xiàn):

public class BufferPerformanceTest {
    private static final int BUFFER_SIZE = 1024 * 1024; // 1MB大小
    private static final int ITERATIONS = 1000; // 測(cè)試1000次
    public static void main(String[] args) throws Exception {
        // 測(cè)試創(chuàng)建速度
        testAllocation();
        // 測(cè)試I/O速度
        testIO();
        // 測(cè)試讀寫速度
        testMemoryAccess();
    }
    private static void testAllocation() {
        long start, end;
        // 測(cè)試堆內(nèi)存Buffer創(chuàng)建速度
        start = System.nanoTime();
        for (int i = 0; i < ITERATIONS; i++) {
            ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); // 在堆里創(chuàng)建
            buffer.put((byte) 1); // 寫點(diǎn)數(shù)據(jù)
        }
        end = System.nanoTime();
        System.out.println("堆Buffer創(chuàng)建: " + (end - start) / 1000000 + "ms");
        // 測(cè)試直接Buffer創(chuàng)建速度
        start = System.nanoTime();
        for (int i = 0; i < ITERATIONS; i++) {
            ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE); // 在系統(tǒng)內(nèi)存創(chuàng)建
            buffer.put((byte) 1); // 寫點(diǎn)數(shù)據(jù)
        }
        end = System.nanoTime();
        System.out.println("直接Buffer創(chuàng)建: " + (end - start) / 1000000 + "ms");
    }
    private static void testIO() throws Exception {
        File tempFile = File.createTempFile("buffer-test", ".tmp"); // 創(chuàng)建臨時(shí)文件
        tempFile.deleteOnExit(); // 程序結(jié)束時(shí)刪除
        // 準(zhǔn)備測(cè)試數(shù)據(jù)
        ByteBuffer data = ByteBuffer.allocate(BUFFER_SIZE);
        while (data.hasRemaining()) {
            data.put((byte) 'A'); // 填充數(shù)據(jù)
        }
        data.flip(); // 切換到讀模式
        // 測(cè)試堆Buffer的I/O速度
        ByteBuffer heapBuffer = ByteBuffer.allocate(BUFFER_SIZE);
        testFileIO(heapBuffer, tempFile, "堆Buffer I/O");
        // 測(cè)試直接Buffer的I/O速度
        ByteBuffer directBuffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
        testFileIO(directBuffer, tempFile, "直接Buffer I/O");
    }
    private static void testFileIO(ByteBuffer buffer, File file, String label) throws Exception {
        FileChannel channel = new FileOutputStream(file).getChannel(); // 獲取文件通道
        long start = System.nanoTime(); // 開始計(jì)時(shí)
        for (int i = 0; i < ITERATIONS; i++) {
            buffer.clear(); // 清空Buffer,準(zhǔn)備寫入
            buffer.put(new byte[BUFFER_SIZE]); // 寫入數(shù)據(jù)
            buffer.flip(); // 切換到讀模式
            while (buffer.hasRemaining()) {
                channel.write(buffer); // 寫到文件
            }
        }
        channel.close(); // 關(guān)閉通道
        long end = System.nanoTime(); // 結(jié)束計(jì)時(shí)
        System.out.println(label + ": " + (end - start) / 1000000 + "ms");
    }
    private static void testMemoryAccess() {
        ByteBuffer heapBuffer = ByteBuffer.allocate(BUFFER_SIZE); // 堆Buffer
        ByteBuffer directBuffer = ByteBuffer.allocateDirect(BUFFER_SIZE); // 直接Buffer
        // 測(cè)試堆Buffer讀寫速度
        long start = System.nanoTime();
        for (int i = 0; i < ITERATIONS; i++) {
            for (int j = 0; j < 1024; j++) {
                heapBuffer.put(j, (byte) j); // 在指定位置寫入
            }
            for (int j = 0; j < 1024; j++) {
                byte b = heapBuffer.get(j); // 從指定位置讀取
            }
        }
        long end = System.nanoTime();
        System.out.println("堆Buffer讀寫: " + (end - start) / 1000000 + "ms");
        // 測(cè)試直接Buffer讀寫速度
        start = System.nanoTime();
        for (int i = 0; i < ITERATIONS; i++) {
            for (int j = 0; j < 1024; j++) {
                directBuffer.put(j, (byte) j); // 在指定位置寫入
            }
            for (int j = 0; j < 1024; j++) {
                byte b = directBuffer.get(j); // 從指定位置讀取
            }
        }
        end = System.nanoTime();
        System.out.println("直接Buffer讀寫: " + (end - start) / 1000000 + "ms");
    }
}

4.4 選擇合適的緩沖區(qū)類型

根據(jù)性能特點(diǎn),可以按照以下原則選擇Buffer類型:

場(chǎng)景推薦Buffer類型原因
大文件I/O直接Buffer不用復(fù)制內(nèi)存,I/O快
網(wǎng)絡(luò)通信直接Buffer減少數(shù)據(jù)復(fù)制,吞吐量高
臨時(shí)小數(shù)據(jù)處理堆Buffer創(chuàng)建快,GC友好
頻繁創(chuàng)建銷毀堆Buffer避免直接Buffer創(chuàng)建的開銷
長(zhǎng)期重用的Buffer直接Buffer一次創(chuàng)建多次使用,攤銷成本

在物聯(lián)網(wǎng)平臺(tái)的實(shí)際應(yīng)用中,通常會(huì)根據(jù)不同場(chǎng)景選擇不同Buffer類型:

  1. 設(shè)備數(shù)據(jù)采集:用直接Buffer處理大量傳感器數(shù)據(jù)
  2. 配置信息傳輸:用堆Buffer處理小型配置數(shù)據(jù)
  3. 文件存儲(chǔ):用直接Buffer或MappedByteBuffer處理大型日志文件
  4. 實(shí)時(shí)數(shù)據(jù)處理:用直接Buffer提高網(wǎng)絡(luò)通信效率

5 總結(jié)

Buffer是Java NIO的核心組件,就像一個(gè)智能的數(shù)據(jù)容器,讓我們能高效地處理各種數(shù)據(jù)。通過掌握Buffer的工作原理、核心屬性和操作方法,以及兩種Buffer類型的性能特點(diǎn),我們就能在物聯(lián)網(wǎng)平臺(tái)等高性能應(yīng)用中做出更好的技術(shù)選擇。

Buffer的核心價(jià)值:

  1. 和Channel完美配合:讓I/O操作變得高效
  2. 靈活的內(nèi)存管理:既能用堆內(nèi)存,也能用系統(tǒng)內(nèi)存
  3. 精確的狀態(tài)控制:通過position、limit、capacity準(zhǔn)確控制數(shù)據(jù)讀寫
  4. 類型安全:針對(duì)不同數(shù)據(jù)類型提供專門的Buffer

掌握了Buffer,我們就為學(xué)習(xí)Java NIO打下了堅(jiān)實(shí)基礎(chǔ)。下一篇文章,我們將深入探討Selector選擇器,看看它如何實(shí)現(xiàn)多路復(fù)用I/O,讓一個(gè)線程同時(shí)處理多個(gè)連接。

到此這篇關(guān)于Java Buffer緩沖區(qū)操作與內(nèi)存管理的文章就介紹到這了,更多相關(guān)Java Buffer緩沖區(qū)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java基礎(chǔ)之位運(yùn)算知識(shí)總結(jié)

    Java基礎(chǔ)之位運(yùn)算知識(shí)總結(jié)

    最近接觸到了java位運(yùn)算,之前對(duì)位運(yùn)算的了解僅僅停留在表現(xiàn)結(jié)果上,乘2除以2,對(duì)背后的原理并不了解,現(xiàn)在學(xué)習(xí)記錄一下,需要的朋友可以參考下
    2021-05-05
  • 在SpringBoot里自定義Spring MVC配置的三種方法

    在SpringBoot里自定義Spring MVC配置的三種方法

    SpringBoot幫我們自動(dòng)配好了 MVC 的核心組件,但實(shí)際開發(fā)中,光用默認(rèn)配置肯定不夠今天就教你 3 種自定義 Spring MVC 配置的方法,從簡(jiǎn)單到復(fù)雜,新手也能一步步跟著做,需要的朋友可以參考下
    2026-03-03
  • idea2023.3安裝及配置詳細(xì)圖文教程

    idea2023.3安裝及配置詳細(xì)圖文教程

    IDEA全稱IntelliJ?IDEA,是Java語言對(duì)的集成開發(fā)環(huán)境,IDEA在業(yè)界被認(rèn)為是公認(rèn)最好的Java開發(fā)工具,這篇文章主要給大家介紹了關(guān)于idea2023.3安裝及配置的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • Java編程實(shí)現(xiàn)用hash方法切割文件

    Java編程實(shí)現(xiàn)用hash方法切割文件

    這篇文章主要介紹了Java編程實(shí)現(xiàn)用hash方法切割文件,簡(jiǎn)單介紹了hash的概念,然后分享了使用方法示例,具有一定借鑒價(jià)值,需要的朋友可以了解下。
    2017-12-12
  • springboot實(shí)現(xiàn)基于aop的切面日志

    springboot實(shí)現(xiàn)基于aop的切面日志

    這篇文章主要為大家詳細(xì)介紹了springboot實(shí)現(xiàn)基于aop的切面日志,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • java double 溢出報(bào)錯(cuò)的問題解決

    java double 溢出報(bào)錯(cuò)的問題解決

    在進(jìn)行Java開發(fā)時(shí),經(jīng)常會(huì)遇到數(shù)字溢出的問題,這個(gè)問題在很多程序中都非常常見,尤其是在進(jìn)行數(shù)值計(jì)算的時(shí)候,本文就來介紹一下如何解決,感興趣的可以了解一下
    2025-09-09
  • Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(9)

    Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(9)

    下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望可以幫到你
    2021-07-07
  • 分享Java8中通過Stream對(duì)列表進(jìn)行去重的實(shí)現(xiàn)

    分享Java8中通過Stream對(duì)列表進(jìn)行去重的實(shí)現(xiàn)

    本文主要介紹了分享Java8中通過Stream對(duì)列表進(jìn)行去重的實(shí)現(xiàn),包括兩種方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-11-11
  • SpringBoot實(shí)現(xiàn)Read Through模式的操作過程

    SpringBoot實(shí)現(xiàn)Read Through模式的操作過程

    Read Through模式通常是指一種緩存策略,其中當(dāng)應(yīng)用程序嘗試讀取數(shù)據(jù)時(shí),緩存系統(tǒng)首先被檢查以查看數(shù)據(jù)是否已經(jīng)存在于緩存中,這篇文章主要介紹了SpringBoot實(shí)現(xiàn)Read Through模式,需要的朋友可以參考下
    2024-07-07
  • springMVC盜鏈接詳解

    springMVC盜鏈接詳解

    這篇文章主要為大家詳細(xì)介紹了SpringMVC盜鏈接詳解,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能給你帶來幫助
    2021-07-07

最新評(píng)論

沛县| 西昌市| 丰镇市| 齐河县| 二连浩特市| 外汇| 安乡县| 诸暨市| 六枝特区| 东台市| 大渡口区| 卢龙县| 海原县| 潜江市| 万山特区| 武鸣县| 大理市| 白银市| 广宗县| 宁德市| 建阳市| 景德镇市| 襄城县| 胶南市| 广昌县| 翁源县| 砚山县| 沙湾县| 高台县| 福泉市| 甘孜| 疏勒县| 罗江县| 黔江区| 庆城县| 清流县| 灵丘县| 民乐县| 北辰区| 济宁市| 夹江县|