日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Buffer的工作方式

發布時間:2023/11/27 生活经验 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Buffer的工作方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、Buffer的工作方式
  前面《java NIO的工作方式》介紹了Selector檢測到通信信道I/O有數據傳輸時,通過select()方法取得SocketChannel,將數據讀取或寫入Buffer緩沖區,下面討論Buffer如何接受和寫出數據。通過查看JDK源碼可知道,Buffer的構造函數

 Buffer(int mark, int pos, int lim, int cap) {	// package-privateif (cap < 0)throw new IllegalArgumentException();this.capacity = cap;limit(lim);position(pos);if (mark >= 0) {if (mark > pos)throw new IllegalArgumentException();this.mark = mark;}}

  Buffer可以簡單的理解為一組基本數據類型的元素列表,它通過幾個變量來保存這個數據的當前位置狀態,也就是四個索引

    private int mark = -1;private int position = 0;private int limit;private int capacity;

表1-1 Buffer中的索引及說明

在實際操作數據時他們關系如圖1-2所示。

我們通過ByteBuffer.allocate(11)方法創建一個11個byte的數組緩沖區,初始狀態如圖1-2所示,position的位置為0,capacity和limit默認都是數組長度。當我們寫入5個字節時位置變化如圖1-3所示。

注意:我們查看ByteBuffer.allocate()方法源碼可知,執行的是以下代碼

ByteBuffer(int mark, int pos, int lim, int cap,	// package-privatebyte[] hb, int offset){super(mark, pos, lim, cap);this.hb = hb;this.offset = offset;}public static ByteBuffer allocate(int capacity) {if (capacity < 0)throw new IllegalArgumentException();return new HeapByteBuffer(capacity, capacity);}

返回的是HeapByteBuffer又是ByteBuffer的子類,并且在HeapByteBuffer的構造方法中執行的是這樣一個語句:

super(-1, 0, lim, cap, new byte[cap], 0);

也就是說調用的還是ByteBuffer中的構造方法,包范圍內使用。這個方法做了如下工作,首先調用Buffer的構 造方法,依次初始化mark、position、limit、capacity,然后初始化ByteBuffer的屬性byte數組,接著初始 offset,這樣使用allocate方法就可以構造出一個ByteBuffer對象了。


這時我們需要將緩沖區的5個字節數據寫入Channel通信信道,所以我們調用byteBuffer.flip()方法,查看源碼得知

 public final Buffer flip() {limit = position;position = 0;mark = -1;return this;}

limit走到position的位置,而position回到了初始位置0,倒轉了緩沖區,數組的狀態發生如圖1-4所示的變化。

這時底層操作系統就可以從緩沖區中正確讀取這5個字節數據并發送出去了。在下一次寫數據之前我們在調一下clear()方法,緩沖區的索引狀態又回到初始位置。

public final Buffer clear() {position = 0;limit = capacity;mark = -1;return this;}

  這里還要說明一下mark,當我們調用mark()方法時,它將記錄當前position的前一個位置,當我們調用reset時,position將恢復mark記錄下來的值。還有一點需要說明,通過Channel獲取I/O數據首先要經過操作系統的Socket緩沖區再將數據復制到Buffer中,這個操作系統緩沖區就是底層的TCP協議關聯的RecvQ或SendQ隊列,從操作系統緩沖區到用戶緩沖區復制數據比較耗性能,Buffer提供了另外一種直接操作操作系統緩沖區的方式,即ByteBuffer.allocateDirector(size),

 public static ByteBuffer allocateDirect(int capacity) {return new DirectByteBuffer(capacity);}

這個方法返回的DirectorByteBuffer就是與底層存儲空間關聯的緩沖區,它通過Native代碼操作非JVM堆的內存空間。每次創建或者釋放的時候都調用一次System.gc()。注意,在使用DirectorByteBuffer時可能會引起JVM內存泄露問題。DirectByteBuffer和Non-Direct Buffer(HeapByteBuffer)對比如圖1-5所示。

轉載于:https://www.cnblogs.com/wcyBlog/p/4719352.html

總結

以上是生活随笔為你收集整理的Buffer的工作方式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。