精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Node Buffer/Stream內存策略分析

開發 前端
在Node 中,Buffer 是一個廣泛用到的類,本文將從三個層次來分析其內存策略

在Node 中,Buffer 是一個廣泛用到的類,本文將從以下層次來分析其內存策略:

◆ User 層面,即Node lib/*.js 或用戶自己的Js 文件調用 new Buffer

◆ Socekt read/write

◆ File read/write

51CTO推薦專題:Node.js專區

User Buffer

在 lib/buffer.js 模塊中,有個模塊私有變量 pool, 它指向當前的一個8K 的slab :

  1. Buffer.poolSize = 8 * 1024;  
  2. var pool;  
  3.  
  4. function allocPool() {  
  5.   pool = new SlowBuffer(Buffer.poolSize);  
  6.   pool.used = 0;  

SlowBuffer 為 src/node_buffer.cc 導出,當用戶調用new Buffer時 ,如果你要申請的空間大于8K,Node 會直接調用SlowBuffer ,如果小于8K ,新的Buffer 會建立在當前slab 之上:

◆ 新創建的Buffer的 parent成員變量會指向這個slab ,

◆ offset 變量指向在這個slab 中的偏移:

  1. if (!pool || pool.length - pool.used < this.length) allocPool();  
  2. this.parent = pool;  
  3. this.offset = pool.used;  
  4. pool.used += this.length; 

比如當你需要2K 的空間時 : new Buffer(2*1024),它會檢查這個slab 的剩余空間,如果有剩余,則分配給你這段可用空間,并把當前 slab 的已用空間 used += 2*1024

比如當我們連續兩次調用new Buffer(2*1024)時 :

 

 

當我們再次申請一個5K 的空間時,當前的pool 僅有4K 可用,所以這時node會再次申請一個8K 的slab ,并把當前的pool 指向它 ,注意此時原先的slab 會有4K空間被浪費:

 

 

此時原先的slab 被兩個2K 的 Buffer 所引用,所以當這兩個Buffer 引用都變為null 后,V8 認為可以銷毀這個slab。

注意,假如我們的某一個slab被一個1Byte 的Buffer 所引用 ,那么,即使其他所有的引用都已經變為null ,這塊8K 的slab 也不會被回收:

 

 

Socket 讀寫

首先讓我們看stream read 的情況:

在stream_wrap 當中,此時的策略與用戶層的 new Buffer 相似,只是slab 的 size 變為 1MB ,此時我們需要考慮socket “讀操作” 緩沖區大小問題,設想以下,假如我們數據長度為30K,而我們的緩沖區大小僅為2K,這意味著我們至少調用15次socket read操作,要觸發15次 on(“data”) 事件,每次都需要把這個事件及數據從libuv 層次傳遞到用戶js 層次,這是極其低效的,所以我們需要設置一個較大的緩沖區,在libuv 的 unix/stream.c ,當綁定socket 的 watcher read 事件被觸發時,會調用uv__read 函數,其固化了buffer 大小為64*1024 :

  1. ...  
  2. buf = stream->alloc_cb((uv_handle_t*)stream, 64 * 1024);  
  3. ... 

alloc_cb 定義在 stream_wrap.cc 中

uv_buf_t StreamWrap::OnAlloc(uv_handle_t* handle, size_t suggested_size)

 

 

但事實上我們知道,我們socket read 一般很少會有64K 大小,比如假如nread 僅為 2k,此時我們為了避免浪費,可以重設slab_used :

  1. if (handle_that_last_alloced == handle) {  
  2. slab_used -= (buf.len - nread);  

 

 

敬請注意,我們之所以能夠這么做,是因為當檢測到socket 上read事件時才分配緩沖區, alloc_cb →socket read → read callback 這一過程是順序進行的,沒有外來的干擾!(我不明白為何node 還要加上一次判斷 if (handle_that_last_alloced == handle) ,深究的可以告訴我)

我們看到,在socket read 的情況下,緩沖區的管理在stream_wrap 中控制,uv steram.c 執行讀操作,返回的回調函數也是在stream_wrap 中定義,然后把讀取到的Buffe 層層傳遞給user 的js當中,即我們的on(“data”) 事件,這個過程中沒有額外的內存拷貝,還是相當高效的, 不過有個問題:假使你持久引用了一個有stream.read 上浮的Buffer ,你將導致其所引用的那個1M 的slab 得不到釋放!

我們在來看 Socket.prototype.write ,當你傳入一個 string 時,node 會自動生成一個Buffer ,如果你本身就是Buffer ,那就省了這一步 (注意調用的是user 層面的 new Buffer):

  1. // Change strings to buffers. SLOW  
  2. if (typeof data == 'string') {  
  3. data = new Buffer(data, encoding);  

然后這個Buffer 對應的指針會層層傳遞,直至 uv 的stream.c 的相應的 write 函數,這個過程也不會再有額外的拷貝操作,尤其要注意的是:當你直接傳入一個Buffer 時,直至socket.write 回調返回表示結束,此過程中你不應該再修改它,因為底層正在或將要操作它!

文件讀寫

regular file 的write 和 socket 比較類似,沒什么亮點,我們重點來看 file read。

關于IO 操作時bufsize 大小的重要性,上文已有介紹,記得APUE 中 steven 老先生也有專門的測試結果,此處不再贅述,

在 fs.ReadStream 時,我們可以傳入一些參數:

  1. { flags: 'r',  
  2. encoding: null,  
  3. fd: null,  
  4. mode: 0666,  
  5. bufferSize: 64 * 1024  

默認bufsize 為 64K ,但在 lib/fs.js 中,還有一個poolSize 控制變量:

  1. var kPoolSize = 40 * 1024; 

當node 最終實際調用fs.read 時:

  1. var thisPool = pool;  
  2. var toRead = Math.min(pool.length - pool.used, this.bufferSize);  
  3. var start = pool.used; 

Node 會對用戶傳入的bufsize 與 當前pool 的剩余空間作比較,取其小者而用之,所以默認的64*1024 大小其實是永遠不會生效的。

好吧,40K 大小也可以接受,但如果你要讀取的文件比較小,比如1K ,2K 級別的比較多,這時我們預留40K 的buf ,當讀返回時,其實只用到了1K 或 2K ,這時候,Node 不會再像socket.read 那樣,再把 pool.used 減去 39K 或 38K ,因為我們實際的fs.read 操作是在另一獨立線程中執行的,即 buf alloc → fs read → read cb 這一個過程不是順序的,我們不能再像socket.read 那樣重新設置pool used !這種情況下內存的浪費相當嚴重!

所以當你想緩存大量小文件時,如靜態服務器,我的建議是:自己分配大塊Buffer ,然后把從fs.readStream 上浮的Buffer 拷貝到我們自己的大塊Buffer 中,然后在這個大塊Buffer 上做 slice生成相應的小Buffer ,這樣我們就沒有引用readStream 上浮的Buffer ,使其可以被V8 回收,當然如果你內存足夠你揮霍,當我啥都沒說…

內存池

再來看底層的node_buffer :

void Buffer::Replace(char *data, size_t length, free_callback callback, void *hint)

這個函數的內存操作很單純:

  1. ….  
  2.  
  3. delete [] data_;  
  4.  
  5. ….  
  6.  
  7. data_ = new char[length_]; 

其實通過上面分析可知,一個繁忙的網絡服務器,很可能會頻繁的new/delete 8K / 1M 的內存塊,如果是靜態文件服務,可能還會有頻繁的40K 內存塊的操作,所以我試著對node 添加了 8K 內存塊的內存池控制,服務繁忙時命中率無限接近100%,可惜總體性能提升沒有達到預期,在此就不現拙了,有興趣的同學可以自己hack 玩玩,有成果了可以知會我一聲(http://weibo.com/windyrobin)…

小節:

由以上分析,我們可知

◆ 不要輕易持久引用由 socket.readStream 或 fs.readStream 上浮的Buffe

◆ 當你調用stream.write 并直接傳遞Buffer 進去時,在此操作返回之前,你不應該再修改它

◆ 當調用fs.readStream 時,如果你對文件大小有估值,盡量傳入較接近的bufsize

◆ 當你持久引用一個Buffer 時,哪怕它只有一個字節,也可能導致其依賴的slab (可能是8K /1M…)得不到釋放

附:以上分析基于node 0.6 系列,就這方面的問題,我已提交了幾個Issue 給 Node 官方,開發人員正在對以上暴露的問題就行改進:

原文:http://cnodejs.org/blog/?p=4186

【編輯推薦】

  1. Node.js開發的桌面應用TermKit介紹
  2. Node.js提速指南
  3. Node.js v0.6.0穩定版發布 附下載
  4. Node.js初體驗
  5. 如何安裝Node.js
責任編輯:陳貽新 來源: cnodejs
相關推薦

2017-03-20 13:43:51

Node.js內存泄漏

2017-03-19 16:40:28

漏洞Node.js內存泄漏

2020-01-03 16:04:10

Node.js內存泄漏

2021-03-01 08:03:26

Node.jsStream模塊

2023-10-26 07:13:14

Redis內存淘汰

2021-10-16 05:00:32

.js Buffer模塊

2021-08-26 13:57:56

Node.jsEncodingBuffer

2020-12-23 13:14:00

LinuxLinux內存Swap

2017-08-22 14:26:39

Linuxbuffercache

2021-03-30 10:50:18

Linux內存命令

2020-04-15 15:48:03

Node.jsstream前端

2016-12-05 16:33:30

2018-08-03 09:07:40

Linux內存buffercache

2010-06-21 09:34:17

GPU stream

2021-07-08 09:48:01

NodeBuffer亂碼

2020-07-17 21:15:08

Redis內存數據庫

2024-10-08 10:13:17

2023-03-14 11:00:05

過期策略Redis

2010-09-17 16:14:22

Java內存分配

2016-06-15 10:35:59

云計算
點贊
收藏

51CTO技術棧公眾號

免费人成视频在线播放| 一区二区三区在线观看www| 久久久久亚洲av成人片| 美女视频亚洲色图| 欧美中文字幕不卡| 免费看黄色a级片| 亚洲日本中文字幕在线| 九九国产精品视频| 欧美亚洲成人精品| 欧美国产日韩在线观看成人| 亚洲区小说区图片区qvod按摩| 欧美日韩三级一区二区| 国产手机免费视频| 日本三级视频在线播放| 国产69精品久久99不卡| 国产精品三级美女白浆呻吟| 国产在线视频卡一卡二| 日韩黄色大片网站| 亚洲精品一区二区久| 手机在线播放av| 国产精品原创视频| 狠狠综合久久av一区二区小说| 吴梦梦av在线| 大乳在线免费观看| 99精品国产一区二区三区不卡| 国产中文日韩欧美| 好吊色在线视频| 日韩午夜黄色| 欧美激情18p| 免费看特级毛片| 国产亚洲一区二区三区啪| 精品88久久久久88久久久| www午夜视频| 成人免费av电影| 欧美日韩一区二区在线| 亚洲精品无码国产| 日韩成人伦理| 亚洲精品免费视频| av磁力番号网| 国产在线1区| 一区在线观看视频| 手机在线观看国产精品| 青青色在线视频| 99精品国产热久久91蜜凸| av资源站久久亚洲| www.97超碰| 国产黑丝在线一区二区三区| 成人免费大片黄在线播放| 中文字幕在线一| 日本午夜一本久久久综合| 国产99久久精品一区二区 夜夜躁日日躁 | 国产免费av一区| 99av国产精品欲麻豆| 久久久久久久久久av| 久久免费视频精品| 亚洲视频综合| 国产91成人在在线播放| 精品国产一区二区三区四| 国产日韩一区二区三区在线| 97久久国产精品| 毛片视频网站在线观看| 亚洲女同在线| 国产精品va在线播放我和闺蜜| 午夜精品一区二| 蜜臀va亚洲va欧美va天堂 | 亚洲天堂网视频| 另类小说一区二区三区| 成人免费黄色网| 精品人妻一区二区三区浪潮在线 | 免费在线黄色网| 欧美激情精品久久久六区热门| 欧美理论电影在线播放| 国产在线欧美在线| 天堂成人国产精品一区| 国产有码一区二区| 亚洲国产综合网| 91色|porny| 亚洲欧美在线网| 日韩专区av| 欧美性猛交xxx| 天天色综合天天色| **爰片久久毛片| 精品网站999www| 男人天堂资源网| 亚洲婷婷在线| 国产精品久久久久久av福利| 国产女人18毛片18精品| 99久久精品国产导航| 日韩高清av电影| 国产黄色在线免费观看| 欧美日韩性视频| 天堂中文av在线| 久久香蕉网站| www.亚洲成人| 国偷自拍第113页| 精品一区二区av| 精品久久久久亚洲| 一广人看www在线观看免费视频| 一区二区成人在线观看| 日本成人在线免费视频| 中文一区二区三区四区| 亚洲一二三在线| 久久精品99国产精| 日av在线不卡| 国新精品乱码一区二区三区18| 91社区在线高清| 精品久久久久久久中文字幕 | 精品一区二区三区毛片| 欧美xxx网站| 日韩三级免费观看| 山东少妇露脸刺激对白在线| 亚洲国产日韩欧美一区二区三区| 国产精品视频在线播放| 天天摸天天干天天操| 日韩毛片一二三区| 激情视频综合网| 色婷婷综合久久久久久| 欧美黑人巨大xxx极品| 涩涩视频在线观看| 2020国产精品自拍| 欧洲精品一区二区三区久久| 国产精品免费精品自在线观看 | 少妇精品无码一区二区免费视频| 国语精品一区| 91入口在线观看| 日本高清中文字幕在线| 在线一区二区三区| 免费a在线观看播放| 国产精品观看| 亚洲www视频| 精品51国产黑色丝袜高跟鞋| 在线区一区二视频| 免费黄色在线视频| 国产精品久久久久久久久久妞妞| 波多野结衣久草一区| h片在线观看网站| 777久久久精品| 潘金莲一级黄色片| 久久丁香综合五月国产三级网站| 亚洲高清视频一区| 四虎4545www精品视频| 亚洲欧美在线一区二区| 亚洲va在线观看| 99亚偷拍自图区亚洲| 男女啪啪免费视频网站| jazzjazz国产精品麻豆| 欧美激情在线观看| 丰满少妇一级片| 亚洲一区在线视频| 国产激情第一页| 中文亚洲免费| 欧美久久综合性欧美| 亚洲人免费短视频| 中文字幕9999| 国产毛片毛片毛片毛片毛片| 亚洲免费av高清| 极品白嫩的小少妇| 亚洲激情午夜| 免费久久99精品国产自| 久久精品女人天堂av免费观看 | 一级黄色录像视频| 国产福利一区在线| 亚洲 欧美 日韩 国产综合 在线 | 国产免费av一区| 国产午夜精品在线观看| 91制片厂毛片| 中文字幕乱码亚洲无线精品一区| julia一区二区中文久久94| 国产丝袜在线播放| 亚洲美女免费精品视频在线观看| 伊人久久中文字幕| 亚洲三级电影全部在线观看高清| 日本r级电影在线观看| 亚洲网站啪啪| 欧洲精品国产| 国产日韩在线观看视频| 国内精品久久久久久中文字幕| 三级视频在线播放| 9191成人精品久久| 日本一级黄色录像| 国产农村妇女毛片精品久久麻豆| 激情文学亚洲色图| 国产美女一区| 欧美少妇在线观看| 亚洲精品亚洲人成在线观看| 国产精品视频免费观看www| 欧美bbbxxxxx| 中文国产亚洲喷潮| 日批视频免费播放| 欧美乱妇20p| 日韩精品视频免费看| 欧美国产日韩亚洲一区| 自拍视频第一页| 视频一区二区欧美| 丰满女人性猛交| 日韩啪啪网站| 亚洲专区国产精品| 成人在线视频播放| 欧美—级高清免费播放| 国产天堂素人系列在线视频| 日韩视频免费直播| 国产乱码在线观看| 亚洲成精国产精品女| 欧美亚洲色综久久精品国产| 国产成人av一区二区三区在线观看| 亚洲欧洲日产国码无码久久99| 99久久精品国产亚洲精品| 久久青青草原一区二区| 精品国产18久久久久久二百| 日韩暖暖在线视频| 91九色在线播放| 欧美成人免费在线视频| 伦理片一区二区三区| 日韩欧美电影在线| 一区二区国产欧美| 色爱区综合激月婷婷| www.天天色| 一区二区三区中文字幕精品精品| 国产黄色录像视频| 国产丝袜在线精品| 国产高清自拍视频| av亚洲精华国产精华| 美女被艹视频网站| 美女视频一区在线观看| 亚洲中文字幕无码中文字| 国产精品va| 特级西西人体www高清大胆| 欧美高清视频手机在在线| 欧洲精品在线一区| 亚洲系列另类av| 蜜桃传媒视频麻豆第一区免费观看 | 精品va天堂亚洲国产| 国产特级aaaaaa大片| 欧美男女性生活在线直播观看| 免费视频网站在线观看入口| 色综合夜色一区| 依依成人综合网| 欧美午夜影院在线视频| 国产毛片aaa| 欧美午夜电影在线| 精产国品一区二区| 色婷婷久久99综合精品jk白丝| www.欧美色| 欧美综合亚洲图片综合区| 国产精品xxxxxx| 欧美视频一二三区| 国产一区二区三区视频免费观看| 精品视频1区2区3区| 一区二区三区亚洲视频| 欧美日本韩国一区| 国产jzjzjz丝袜老师水多| 欧美一区二区视频网站| 成人1区2区3区| 亚洲成色777777在线观看影院| 六月丁香色婷婷| 亚洲精品国产综合久久| 日本一二三区在线视频| 一本色道久久综合亚洲精品小说| 中文字幕在线观看日本| 久久视频在线播放| 暖暖在线中文免费日本| 97在线视频免费播放| 日韩电影大全网站| 国产人妖伪娘一区91| 久久av网站| 久久99久久99精品蜜柚传媒| 国产精品日韩精品中文字幕| 亚洲自拍三区| 韩日欧美一区| 国产精品99久久免费黑人人妻| 老司机一区二区| 2025中文字幕| 久久久一区二区| 国产亚洲精品久久久久久豆腐| 亚洲乱码国产乱码精品精可以看 | 国产情侣一区| 国产三级国产精品国产专区50| 韩国av一区二区三区四区| 中文字幕无人区二| 国产偷国产偷亚洲高清人白洁| 91精品少妇一区二区三区蜜桃臀| 亚洲一区在线看| 人妻中文字幕一区二区三区| 欧美一级理论片| 青青国产在线| 久久91亚洲人成电影网站| 亚洲妇女成熟| 91视频99| 日韩国产一区| 337p粉嫩大胆噜噜噜鲁| 久久精品国产亚洲aⅴ| 日韩免费高清一区二区| 国产精品乱人伦| 自拍偷拍欧美亚洲| 欧美精品乱码久久久久久 | 91热门视频在线观看| 日韩激情小视频| 日本丶国产丶欧美色综合| av中文字幕观看| 国产一区二区三区在线免费观看| 日韩经典av| 成人乱人伦精品视频在线观看| 天堂俺去俺来也www久久婷婷| 国产又爽又黄ai换脸| 久久国产欧美| 国产情侣久久久久aⅴ免费| 国产精品成人免费在线| 无码aⅴ精品一区二区三区| 精品国产乱码久久久久久图片| av中文资源在线| 日韩av成人在线观看| 国产精品videossex| 国产精品夜夜夜爽张柏芝| 日韩高清欧美激情| 人体私拍套图hdxxxx| 亚洲免费观看视频| 一级片视频网站| 亚洲午夜未删减在线观看 | 日本亚洲三级在线| 亚洲欧美视频在线播放| 亚洲高清视频在线| 精品国产av一区二区| www国产亚洲精品久久网站| 日韩一区二区三区在线免费观看| 国产一区二区三区四区hd| 国模吧视频一区| 九色91porny| 亚洲欧美激情插 | 国产传媒久久久| 久草这里只有精品视频| 激情五月深爱五月| 欧美日韩一级二级| 成人三级黄色免费网站| 国产精品国产福利国产秒拍| 亚洲裸色大胆大尺寸艺术写真| 日本欧美黄色片| 99九九99九九九视频精品| 国产无码精品视频| 亚洲国产天堂久久国产91| 超碰在线最新网址| 久久福利电影| 香蕉久久夜色精品| 谁有免费的黄色网址| 在线一区二区三区四区五区| 中文日本在线观看| 国产精品专区一| 一区二区不卡| 男人女人拔萝卜视频| 亚洲成人自拍一区| 四虎影视精品成人| 欧美中文字幕视频| 国产一区二区三区不卡视频网站 | 福利一区在线观看| 久久视频免费在线观看| 亚洲国产一区自拍| 老司机2019福利精品视频导航| 奇米视频888战线精品播放| 免费人成网站在线观看欧美高清| 国产成人在线网址| 日韩一级免费观看| a级片在线免费观看| 蜜桃视频在线观看91| 奇米精品一区二区三区在线观看| 亚洲精品国产精品乱码在线观看| 91精品国产色综合久久不卡蜜臀| 午夜伦理在线视频| 久久久久一区二区| 青青青爽久久午夜综合久久午夜| 日韩欧美123区| 亚洲第一在线视频| 日韩成人亚洲| 男女啪啪的视频| 91亚洲资源网| 一区二区视频网站| 欧美精品九九久久| 凹凸成人精品亚洲精品密奴| 在线观看网站黄| 狠狠做深爱婷婷久久综合一区| www.视频在线.com| 国产精品二区三区| 男女激情视频一区| 日本少妇bbwbbw精品| 揄拍成人国产精品视频| 午夜日韩影院| 99热手机在线| 亚洲国产精品综合小说图片区| 嫩草研究院在线观看| 亚洲在线观看视频| 老司机午夜精品视频在线观看| 亚洲波多野结衣| 亚洲欧美国产精品专区久久| 国产精品麻豆| 亚洲综合在线网站| 亚洲综合清纯丝袜自拍| 国产一区精品| 国产精品亚洲不卡a| 久久精品国产成人一区二区三区| 国产精品成人免费一区二区视频| 中文字幕在线国产精品| 久久精品色播|