Node.js排除內存泄漏演示

用於定位node內存泄漏的工具經常使用的有:javascript

在演示DEMO以前能夠了解點基本前置知識

關於Node的堆內存與堆外內存小記。java

  1. 受到V8 GC的主要是堆內存。
  2. Node中的內存並不是都是經過V8來進行分配的,可經過堆中的內存用量(heapUsed)老是小於進程常駐內存(rss)看出。 對於那些不是經過V8來分配內存的咱們稱爲堆外內存,好比Buffer,Buffer是基於C++的不是V8(從下面的demo中rss與external的值能夠看出)。 external表明 V8 管理的,綁定到 Javascript 的 C++ 對象的內存使用狀況。
  3. 所以代表堆外內存是能夠突破內存限制問題。

使用node-heapdump排除內存泄漏的DEMO

這裏主要演示node-heapdump, node-memwatch好久沒有維護了。node

環境安裝

  • node.js
  • node-gyp
  • mac下須要安裝 xcode-select --install
  • mac下安裝xcode後 sudo xcode-select --switch /Library/Developer/CommandLineTools/
  • node-heapdump

代碼

const heapdump = require('heapdump')
const http = require('http')

const leakArray = []
const leak = function() {
	leakArray.push(`leak: ${Math.random()}`)
}

http.createServer(function(req, res) {
	// 每次訪問node服務。都會往leakArray增長數據,而且不會回收。
	leak()
	res.writeHead(200, {'Content-Type': 'text/plain'})
	res.end('hello node')
}).listen(9999)

console.log('server is running at: http:127.0.0.1:9999/')
複製代碼

而後咱們經過在終經過curl不斷訪問服務器curl http://127.0.0.1:9999模擬用戶訪問,這個時候leakArray數組不斷增大,而且不會被回收。git

在UNIX平臺上,你能夠向服務器進程通發送SIGUSR2信號強制快照。github

 $ kill -USR2 <pid>
複製代碼

mac下查看pidshell

$ lsof -i tcp:9999
複製代碼

這個時候會在你的文件夾生成一個快照,文件名格式默認爲:heapdump-..heapsnapshot。數組

因爲Node是依賴V8引擎執行JavaScript的,Chrome瀏覽器也是,因此咱們能夠藉助Chrome開發者工具中的Memory模塊來分析這些dump文件。首先打開Chrome的開發者工具,切換到Memory,並依次加載dump文件。xcode

關於Summary這個選項,從圖中能夠看出它有Constructor、Distance、Shallow Size、Retained Size共4項。Constructor這列是用類名對變量進行分組;Distance表示和根對象的距離,越小表示和根對象越近;Shallow Size表示變量自身的大小,不包含它引用的變量的大小;Retained Size不只包含自身的大小,還包含了引用的變量的大小。瀏覽器

從圖中能夠看出,(string)那一行的Shallow Size和Retained Size都佔據了100%的內存。bash

咱們直接查看distance(20)最遠的那一行。

而後咱們詳情看下leak()。

當你再詳細查看leakArray你就發現這裏存儲了大量的leak字符串,它們一直未獲得回收。

參考資料

  • 深刻淺出node.js

PS: 感興趣的能夠關注下公衆號。

相關文章
相關標籤/搜索