nodejs記憶體洩漏分析 完整步驟

2021-10-18 08:41:10 字數 2722 閱讀 9750

我們的nodejs信令伺服器線上執行,但是每當使用者量很大或者幾天不重啟,就會發現記憶體飆公升,之後就會cpu飆高,不確定是否有關,以至於我們必須每天凌晨定時重啟伺服器釋放記憶體,但是還是有時出現事故,決心徹底解決nodejs記憶體洩露的問題

網上看見這個工具直接整合到**裡,就可以通過介面蒐集cpu和memery的資訊,但是檢測memery並沒有提供有用的資訊,而是提示沒問題,所以不太靠譜,檢測cpu的簡單用了幾次,不太確定好不好用,而且使用要非常小心,如果你的記憶體特別大,而且是線上,千萬不要試著這時候分析記憶體,這樣會瞬間吃光你的所有記憶體,機器停止響應,比記憶體oom還要恐怖,必須強制重啟機器才能解決,感覺是這個工具的問題

**如下(示例):

const heapdump = require('heapdump')

process.chdir(config.snapshotdir);設定快照儲存路徑

heapdump.writesnapshot()

這個是比較靠譜的一種方法,也是我真正解決問題的途徑,可以通過一條http請求或者乙個websocket信令觸發庫快照抓取,也可以主動監控heapused的記憶體觸發快照抓取。

快照抓取之後,就要用分析工具去分析記憶體中到底儲存的什麼資料了,首選chrome的快照分析工具如下圖:

load之後就可以看到幾個選項了:

shallow size就是物件本身占用記憶體的大小,retained size就是該物件被gc之後所能**記憶體的總和,constructor 是各個資料結構的個數統計,

我們主要看retained size,利用自動排序,關注下記憶體比較大的資料結構,就可能是我們的記憶體洩漏點了

與我們程式強相關的就是這幾個物件了,明顯需要釋放卻沒有釋放的,關鍵點來了,為什麼沒有釋放,之前已經查過一遍了,從map或者array中已經刪除了,到底是**還在引用導致沒有釋放呢,這就需要你去擼**了,主要看**把這個物件引用了,但是此時的我還是一臉懵逼,不知道該從**去著手。

終於在網上發現一篇除錯nodejs記憶體洩露的文章,想著三個臭皮匠頂個諸葛亮,借鑑下前人的力量,這段**引起了我的注意:

這裡以一段經典的記憶體洩漏**作為測試**:

const heapdump = require('heapdump')

let leakobject = null

let count = 0

setinterval(function testmemoryleak()

} leakobject =

}}, 1000)

為什麼這段程式會發生記憶體洩漏呢?首先我們要明白閉包的原理:同乙個函式內部的閉包作用域只有乙個,所有閉包共享。在執行函式的時候,如果遇到閉包,則會建立閉包作用域的記憶體空間,將該閉包所用到的區域性變數新增進去,然後再遇到閉包,會在之前建立好的作用域空間新增此閉包會用到而前閉包沒用到的變數。函式結束時,清除沒有被閉包作用域引用的變數。這段**記憶體洩露原因是:在 testmemoryleak 函式內有兩個閉包:unused 和 leakmethod。unused 這個閉包引用了父作用域中的 originleakobject 變數,如果沒有後面的 leakmethod,則會在函式結束後被清除,閉包作用域也跟著被清除了。因為後面的 leakobject 是全域性變數,即 leakmethod 是全域性變數,它引用的閉包作用域(包含了 unused 所引用的 originleakobject)不會釋放。而隨著 testmemoryleak 不斷的呼叫,originleakobject 指向前一次的 leakobject,下次的 leakobject.leakmethod 又會引用之前的 originleakobject,從而形成乙個閉包引用鏈,而 leakstr 是乙個大字串,得不到釋放,從而造成了記憶體洩漏。

彷彿看到一絲黎明前的曙光有木有,不知道能不能和我們的**產生化學反應呢?

然後再publisher的物件中找到了這麼一句**,原作者傳入了this物件,他去幹嘛,有沒有釋放呢?

原作者的本意是給log增加乙個固定的log頭,這樣就不用去每次打日誌都去加一些公用的資訊,但是log物件卻是全域性的,一直沒有釋放,導致一直繫結這個傳入的物件,這也是pub和sub一直增長沒有釋放的真真原因,可謂是好心辦壞事啊,困擾了幾個月的問題,**就是這幾行**。

本文只是簡單的舉了乙個實際的專案中遇到的記憶體洩露的問題,感謝發達的網路,不然可能真的無從下手呢,很久都沒有解決就是因為,一開始不知道怎麼下手,想抓取快照,確是一直不能成功,伺服器記憶體有限,導致一抓取就會導致oom,最近抓取成功分析也就水到渠成了,學無止境,歡迎大神討論

CSDN洩漏資料完整分析

1.最常用的前50個密碼 數量 密碼 235037 123456789 212761 12345678 76349 11111111 46054 dearbook 34953 00000000 20010 123123123 17794 1234567890 15033 88888888 6995 ...

MAT分析記憶體洩漏

mat常用的功能 histogram可以列出記憶體中每個物件的名字 數量以及大小。dominator tree會將所有記憶體中的物件按大小進行排序,並且我們可以分析物件之間的引用結構。摘取 這是dominator tree中比較常用的一種分析方式,即搜尋大記憶體物件通向gc roots的路徑,因為記...

C 記憶體洩漏原因分析

一.記憶體洩漏 1.什麼是記憶體洩漏 記憶體洩漏是指在程式中申請了記憶體沒有呼叫釋放函式,導致記憶體沒有被系統 程式記憶體會不斷增大,最後導致系統記憶體不足,程式卡頓或崩潰。2.記憶體洩漏的原因 1 呼叫new或者malloc申請記憶體後沒有主動呼叫delete或者free。2 在使用多型特性時,基...