公司目前項目用的是express、react、react-router、redux、redis等組建做的同構(gòu)APP,同構(gòu)APP帶來的好處不多說了。
這次主要是闡述一下怎么解決內(nèi)存泄漏的心路歷程。
先貼一張阿里云的圖片,分析一下CPU正常范圍內(nèi)波動,但是內(nèi)存是從300M在兩天的時間緩慢升到1.5G的,并且在用戶請求下來后,內(nèi)存還是一樣的不會釋放,這樣在運行到第三天的時候,內(nèi)存就會飆升到3G左右,雖然是一個8G的物理機,但這種內(nèi)存下,瀏覽器的請求已經(jīng)緩慢到不能忍受了,在運行一段時間后,CPU、內(nèi)存都會超負(fù)荷,這時候網(wǎng)頁請求就一點響應(yīng)都沒有了。

這個問題讓我困擾了三五天的時間,每次都等到內(nèi)存飆升到1.5G的時候,我們手動重啟一下服務(wù),這下內(nèi)存一下被釋放了,請求速度也像脫韁的野馬,快到?jīng)]朋友,網(wǎng)上也有資料說用用
pm2設(shè)置自動重啟,但是我們不能總是靠這種low逼的方式去隱藏這個問題,一點點排查問題吧。
下面主要列出我解決這個問題的經(jīng)過
1、借助性能分析工具,比如node-heapdump,node-memwatch等等工具,然后借助chrome develop tool去做性能分析,但不知是我不會用還是不懂什么原因,就是分析不到那個泄漏點,這個方式以失敗告終。
2、去網(wǎng)上查可能泄漏的原因,比如閉包、循環(huán)引用、大量的loop,然后努力回憶代碼的各種問題,貌似也沒有這種問題,都在很謹(jǐn)慎的使用閉包,因為是同構(gòu)APP,服務(wù)端會讀到前端的很多代碼,會不會是前端代碼哪里寫的不規(guī)范,這一通找,還沒定位到。
3、express middleware哪里沒有寫next導(dǎo)致請求無法釋放,或者是沒有某個請求下沒有響應(yīng),然后把服務(wù)端代碼一通檢查,保證不管什么原因每個請求必須有res.send()或者res.json(),這個檢查過程也讓我們的代碼更加健壯,所以感謝這次內(nèi)存泄漏的問題。
4、此時陷入一個絕境了,靠工具分析沒有找到,或者是不會用工具?what the fuck!總之沒找到。代碼層面都排查一遍了,也沒找到真正的原因,難道真的要靠不斷重啟來解決這個問題。只能去排查第三方包的問題了,然后突然想起前段時間用了一個https://www.npmjs.com/package/memory-cache組建,難道是這個問題?果斷看源碼,會不會因為這個memory-cache的緩存時長是用setTimeout的原因,這個定時器在并發(fā)下無法回收。然后果斷去掉,把緩存用redis去管理,搞定后壓測開始,妥妥的內(nèi)存一直穩(wěn)定在400M左右,并且升上去會隔一段時間會降低下來,有圖為證。
