Nodejs Buffer緩衝區

ㅤㅤㅤ
ㅤㅤㅤ
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ(無論你怎樣地表示憤怒,都不要做出任何無法挽回的事來。——培根)
ㅤㅤㅤ
ㅤㅤㅤ
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ在這裏插入圖片描述

Buffer

  • Nodejs-Buffer歷史

JavaScript 語言自身只有字符串數據類型,沒有二進制數據類型。
但在處理像TCP流或文件流時,必須使用到二進制數據。因此在 Node.js中,定義了一個 Buffer 類,該類用來創建一個專門存放二進制數據的緩存區。
在 Node.js 中,Buffer 類是隨 Node 內核一起發佈的核心庫。Buffer 庫爲 Node.js 帶來了一種存儲原始數據的方法,可以讓 Node.js 處理二進制數據,每當需要在 Node.js 中處理I/O操作中移動的數據時,就有可能使用 Buffer 庫。原始數據存儲在 Buffer 類的實例中。一個 Buffer 類似於一個整數數組,但它對應於 V8 堆內存之外的一塊原始內存。

在v6.0之前創建Buffer對象直接使用new Buffer()構造函數來創建對象實例,但是Buffer對內存的權限操作相比很大,可以直接捕獲一些敏感信息,所以在v6.0以後,官方文檔裏面建議使用 Buffer.from() 接口去創建Buffer對象。

  • 什麼是Buffer

緩衝區(buffer),它是內存空間的一部分。也就是說,在內存空間中預留了一定的存儲空間,這些存儲空間用來緩衝輸入或輸出的數據,這部分預留的空間就叫做緩衝區,顯然緩衝區是具有一定大小的。
緩衝區根據其對應的是輸入設備還是輸出設備,分爲輸入緩衝區和輸出緩衝區。

  • 爲什麼需要Buffer

高速設備與低速設備的不匹配,勢必會讓高速設備花時間等待低速設備,我們可以在這兩者之間設立一個緩衝區。

  • Buffer的作用
  • 可以解除兩者的制約關係,數據可以直接送往緩衝區,高速設備不用再等待低速設備,提高了計算機的效率。
    例如:我們使用打印機打印文檔,由於打印機的打印速度相對較慢,我們先把文檔輸出到打印機相應的緩衝區,打印機再自行逐步打印,這時我們的CPU可以處理別的事情
  • 可以減少數據的讀寫次數,如果每次數據只傳輸一點數據,就需要傳送很多次,這樣會浪費很多時間,因爲開始讀寫與終止讀寫所需要的時間很長,如果將數據送往緩衝區,待緩衝區滿後再進行傳送會大大減少讀寫次數,這樣就可以節省很多時間。
    例如:我們想將數據寫入到磁盤中,不是立馬將數據寫到磁盤中,而是先輸入緩衝區中,當緩衝區滿了以後,再將數據寫入到磁盤中,這樣就可以減少磁盤的讀寫次數,不然磁盤很容易壞掉
  • 簡單來說,緩衝區就是一塊內存區,它用在輸入輸出設備和CPU之間,用來存儲數據。它使得低速的輸入輸出設備和高速的CPU能夠協調工作,避免低速的輸入輸出設備佔用CPU,解放出CPU,使其能夠高效率工作。
  • Buffer的類型
  • 全緩衝
    在這種情況下,當填滿標準I/O緩存後才進行實際I/O操作。全緩衝的典型代表是對磁盤文件的讀寫
  • 行緩衝
    在這種情況下,當在輸入和輸出中遇到換行符時,執行真正的I/O操作。這時,我們輸入的字符先存放在緩衝區,等按下回車鍵換行時才進行實際的I/O操作。典型代表是鍵盤輸入數據
  • 不帶緩衝
    不進行緩衝,標準出錯情況stderr是典型代表,這使得出錯信息可以直接儘快地顯示出來
  • 緩衝區的刷新
    • 緩衝區填滿
    • 關閉文件

緩存(Cache)和緩衝區(Buffer)的區別

  • Buffer的核心作用是用來緩衝,緩和衝擊。比如你每秒要寫100次硬盤,對系統衝擊很大,浪費了大量時間在忙着處理開始寫和結束寫這兩件事嘛。用個buffer暫存起來,變成每10秒寫一次硬盤,對系統的衝擊就很小,寫入效率高了,日子過得爽了。極大緩和了衝擊

  • Cache的核心作用是加快取用的速度。比如你一個很複雜的計算做完了,下次還要用結果,就把結果放手邊一個好拿的地方存着,下次不用再算了。加快了數據取用的速度


Nodejs目前支持的Buffer字符編碼

通過使用字符編碼,可實現 Buffer 實例與 JavaScript 字符串之間的相互轉換,目前所支持的字符編碼

  • ascii 僅適用於 7 位 ASCII 數據。此編碼速度很快,如果設置則會剝離高位。
  • utf8 多字節編碼的 Unicode 字符。許多網頁和其他文檔格式都使用 UTF-8。
  • utf16le 2 或 4 個字節,小端序編碼的 Unicode 字符。支持代理對(U+10000 至 U+10FFFF)。
  • ucs2 utf16le的別名。
  • base64 Base64 編碼。當從字符串創建 Buffer 時,此編碼也會正確地接受 RFC 4648 第 5 節中指定的 “URL 和文件名安全字母”。
  • latin1 一種將 Buffer 編碼成單字節編碼字符串的方法(由 RFC 1345 中的 IANA 定義,第 63 頁,作爲 Latin-1 的補充塊和 C0/C1 控制碼)。
  • binary latin1的別名。
  • hex 將每個字節編碼成兩個十六進制的字符。

Buffer內存機制

值得注意的是,Nodejs的Buffer不向v8申請內存,它通過node的c++模塊申請內存。因此,buffer的內存策略是由c++申請內存,然後,在js中分配內存。
因爲,處理大量的字節數據不能採用需要一點內存就向操作系統申請一點內存的方式,這可能造成大量的內存申請的系統調用,對操作系統有一定壓力

Nodejs採用了 Slab 的分配機制,它有三個狀態

  • full 完全分配狀態
  • partial 部分分配狀態
  • empty 沒有被分配狀態

並且以8kb爲一個界限來區分是小對象還是大對象
在Buffer.js可以看到源碼
Buffer.poolSize = 8 * 1024;


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章