深入淺出NodeJS——記憶體控制

來源:互聯網
上載者:User

標籤:http   java   使用   os   strong   檔案   資料   art   

基於無阻塞、事件驅動建立的Node服務,具有記憶體消耗低的優點,非常適合處理海量的網路請求。

V8的記憶體回收機制與記憶體限制

Javascript和Java類似,由記憶體回收機制來進行自動記憶體管理,而Node是構建在V8虛擬機器基礎上,所以其記憶體回收和V8運行機制息息相關。

V8的記憶體限制:64位系統約為1.4GB、32位系統約為0.7GB

process.memoryUsage(),返回值包括heapTotal代表已申請到的堆記憶體,heapUsed當前使用的記憶體,rss(resident set size)進程的常駐記憶體。

V8的記憶體回收機制

V8採用基於分代式記憶體回收機制,堆記憶體結構如下所示,分為新生代和老生代,通過參數可以設定相應大小,但是一旦設定不能根據使用方式自動擴充。


新生代:複製演算法、Scavenge演算法,一個對象是否從新生代晉陞到老生代主要根據以下兩個條件。

a. 一個對象是否被Scavenge回收過;

b.To空間的記憶體佔用比超過限制(25%);

老生代:Mark-Sweep & Mark-Compact

Mark-Sweep標記清除,只清理死亡對象,記憶體空間會存在大量片段。

Mark-Compact標記整理,標記死亡對象後,將活著的對象往一端移動消除不連續的片段,速度最慢

上述3種記憶體回收方法都需要將應用邏輯暫停下來,待記憶體回收完畢再繼續執行應用邏輯,這種行為稱為stop-the-world

查看記憶體回收日誌:node --trace_gc -e test.js

V8效能分析資料:node --prof test.js   --->v8.log

linux-tick-processor v8.log

高效使用記憶體

JavaScript中範圍分為:函數範圍、with範圍、全域範圍

標示符尋找會先從當前範圍,若沒有找到將會向上級的範圍裡尋找

查看進程記憶體使用量情況:process.memoryUsage()

查看系統記憶體佔用:os.totalmem()和os.freemem(),系統總記憶體和閑置記憶體,以位元組為單位

堆外記憶體:Buffer等

記憶體泄露

記憶體泄露的實質是應當回收的對象出現意外而沒有被回收,變成了常駐在老生代中的對象。

通常造成記憶體泄露原因包括

(1) 緩衝

Javascript對象本身就是key-value形式,可以用作緩衝,但由於缺乏高效淘汰機制存在較多缺陷和問題。

由於模組的緩衝機制,模組是常駐老生代的,在模組設計時,十分小心記憶體泄露。

解決方案:進程外的緩衝,進程自身不儲存狀態,如Redis、memcached

(2) 隊列消費不及時

(3) 範圍未釋放

記憶體泄露排除工具

node-heapdump

node-memwatch

大記憶體使用量

Node中提供stream模組用於處理大檔案,分為可讀和可寫兩種,Node中大部分模組都具有stream的應用如:

fs.createReadStream()、fs.createWriteStream(),可以避免由於V8記憶體限制不能通過fs.readFile()或fs.writeFile()操作大檔案。



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.