NUXT內存泄漏引起問題

原由

項目中使用了nuxtjs框架進行開發,在開發測試過程當中均無出現任何異常。部署上線到正式生產環境以後,運行了五六天以後node異常,服務中止響應,pm2管理平臺沒法恢復應用程序。須要進入生產環境進行重啓項目。查閱運行日誌以後發現生產服務器會緩慢堆積tcp連接。在到必定的程度以後,會引起node程序 cpu 100%佔用,中止響應。最初階段覺得是_nuxt下的文件並未經過nginx訪問,而是經過node進行讀取的,形成文件打開過多,從新配置了nginx靜態文件讀取規則以後,問題依舊。在解決這個問題的過程當中發現某個文章中提到,若是node內存泄漏會形成node進程跑滿當前cpu,而且打開文件數飆增。html

調試

調試工具

  1. node-heapdump
  2. chrome調試工具

調試流程

安裝node-heapdump。node

npm install node-heapdump --save-dev

打開項目根目錄的nuxt.config.js文件,進行heapdump配置。nginx

// 內存快照代碼
 var headpdump = require('heapdump')
//
 setInterval(function () {
   console.log('st headpdump')
   headpdump.writeSnapshot(function(err, filename) {
     console.log('dump written to', filename)
   })
 }, 15000)

module.exports = {...// nuxt配置}

我設定了每1.5秒,heapdump進行內存快照一次。
而且在間隔過程當中進行如下操做。chrome

  1. 載入頁面,等候一次快照
  2. 刷新一次頁面,等候一次快照

等待快照完成以後,heapdump會將快照文件保存在項目根目錄中。npm

接着,咱們打開chrome開發者工具,切換到memory選項卡,點擊load載入hepdump生成在根目錄的文件。
Alt text服務器

分別載入第一次頁面快照,跟刷新一次以後的快照。咱們點擊切換右側下拉箭頭的視圖選項卡類型。點擊切換視圖到Comparison。閉包

Alt text
在等候Chrome比對兩個文件以後,能夠看到第二個文件的內存快照信息。查看右側# Delta選項。
Alt text
能夠看到 刷新一次以後,增長了69個閉包未釋放。
展開閉包(closure)能夠看到大量的request請求未釋放。
因而可知,問題出如今項目中服務端請求服務接口上。框架

解決問題

檢查services文件中的請求方法代碼。frontend

import Urls from './url'
import Fetch from './fetch.js'

let fn = {}
Object.keys(Urls).forEach(key => {
  fn[key] =  (data, headers) => {
    return new Promise((resolve, reject) => {
      resolve(Fetch(Urls[key].url, {method: Urls[key].method, data, headers}))
    })
  }
})

export default fn

發現了問題,services 經過return請求,可是使用的數據都是經過箭頭方法傳遞到下一層,變量被層層引用,這樣會形成閉包沒法徹底釋放。由於傳入的數據一直都有引用沒法gc,這樣也形成了node打開的tcp連接沒法關閉釋放。tcp

咱們修改了services方法,通過修改的代碼以下:

import Urls from './url'
import Fetch from './fetch.js'

let fn = {}
Object.keys(Urls).forEach(key => {
  fn[key] = function (data, headers) {
    return Fetch(Urls[key].url, {method: Urls[key].method, data, headers})
  }
})

export default fn

再次經過調試流程生成內存快照,發現request閉包都回收完畢。內存泄漏問題初步告一段落,項目更新以後已穩定運行。

參考文章來源
http://frontenddev.org/link/j...

文章初次發佈於https://www.yodfz.com/detail/...

相關文章
相關標籤/搜索