最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析Node.js中的內(nèi)存泄漏問(wèn)題

 更新時(shí)間:2015年06月23日 15:27:11   投稿:goldensun  
這篇文章主要介紹了淺析Node.js中的內(nèi)存泄漏問(wèn)題,Node.js是使JavaScript應(yīng)用在服務(wù)器端運(yùn)行的一款框架,需要的朋友可以參考下

 這篇文章是由Mozilla的Identity團(tuán)隊(duì)帶來(lái)的 A Node.JS Holiday Season系列文章的首篇,該團(tuán)隊(duì)上個(gè)月發(fā)布了 Persona的第一個(gè)測(cè)試版本。在開(kāi)發(fā)Persona時(shí)我們構(gòu)建了一系列的工具,包括了從調(diào)試,到本地化,到依賴管理以及更多的方面。在這一系列的文章中我們將與社區(qū)分享我們的經(jīng)驗(yàn)和這些工具,這對(duì)任何想用node.js建立一個(gè)高可用性服務(wù)的人都很有用。我們希望您能喜歡這些文章,并期待看到您的想法和貢獻(xiàn)。

我們將從一篇關(guān)于Node.js的實(shí)質(zhì)性問(wèn)題:內(nèi)存泄漏的主題文章開(kāi)始。我們會(huì)介紹 node-memwatch — 一個(gè)幫助發(fā)現(xiàn)并隔離Node中的內(nèi)存泄漏問(wèn)題的函數(shù)庫(kù)。


為什么自尋煩惱?

關(guān)于追蹤內(nèi)存泄漏問(wèn)得最多的問(wèn)題就是,“為什么要自尋煩惱?”。難道沒(méi)有更緊迫的問(wèn)題需要先解決嗎?為什么不選擇不時(shí)地重啟服務(wù),或?yàn)橹峙涓嗟模遥粒??為了回答這些問(wèn)題,我們提出了以下三點(diǎn)建議:

1.也許你不在乎不斷增長(zhǎng)的內(nèi)存占用,但V8在乎(V8是Node運(yùn)行時(shí)的引擎)。隨著內(nèi)存泄漏的增長(zhǎng),V8對(duì)垃圾收集器越來(lái)越具有攻擊性,這會(huì)使你的應(yīng)用運(yùn)行速度變慢。所以,在Node上,內(nèi)存泄漏會(huì)損害程序性能。

2.內(nèi)存泄漏可能觸發(fā)其他類型的失敗。內(nèi)存泄漏的代碼可能會(huì)持續(xù)的引用有限的資源。你可能會(huì)耗盡文件描述符;你還可能會(huì)突然不能建立新的數(shù)據(jù)庫(kù)連接。這類問(wèn)題可能在你的應(yīng)用耗盡內(nèi)存前很早就會(huì)暴露出來(lái),但它仍然會(huì)是你陷入困境。

3.最后,你的應(yīng)用遲早會(huì)崩潰,并且在你的應(yīng)用受到歡迎時(shí)肯定會(huì)發(fā)生。所有人都會(huì)在Hacker?。危澹鳎笊铣靶δ?,諷刺你,這樣你就悲劇了。

潰千里之堤的蟻穴在哪里?

在構(gòu)建復(fù)雜應(yīng)用的時(shí)候,很多地方都可能發(fā)生內(nèi)存泄露。 閉包可能是最廣為人知也是最聲名狼藉的。因?yàn)殚]包保留了對(duì)其作用域內(nèi)的東西的引用,而這正是通常的內(nèi)存泄露之源。

閉包泄露往往只有在有人去尋找它們的時(shí)候才能發(fā)現(xiàn)。但是在Node的異步世界里,我們隨時(shí)隨地的通過(guò)回調(diào)函數(shù)不停的生成閉包。如果這些回調(diào)函數(shù)沒(méi)有在創(chuàng)建后立刻使用,分配的內(nèi)存就會(huì)持續(xù)增長(zhǎng),那些看起來(lái)沒(méi)有內(nèi)存泄露問(wèn)題的代碼也會(huì)產(chǎn)生泄露。而這種問(wèn)題更難發(fā)現(xiàn)。

你的應(yīng)用也可能由于上游代碼的問(wèn)題導(dǎo)致內(nèi)存泄露。也許你能定位到出現(xiàn)內(nèi)存泄露的代碼,但是你可能只能眼巴巴地盯著你那完美無(wú)缺的代碼然后困惑于這到底是怎么泄露的!


正是這些難以定位的內(nèi)存泄露促使我們想要一個(gè)node-memwatch這樣的工具。傳說(shuō)幾個(gè)月以前,我們的Lloyd Hilaiel把他自己鎖在一個(gè)小房間里兩天,試著追蹤一個(gè)在壓力測(cè)試下變得非常明顯的內(nèi)存泄露問(wèn)題。(順便說(shuō)下,盡請(qǐng)期待Lloyd即將到來(lái)的關(guān)于負(fù)荷測(cè)試的文章)

經(jīng)過(guò)兩天的努力,他終于發(fā)現(xiàn)了Node內(nèi)核中的元兇:http.ClientRequest中的事件監(jiān)聽(tīng)器沒(méi)有被釋放。(最終修復(fù)這個(gè)問(wèn)題的補(bǔ)丁只有兩個(gè)但卻至關(guān)重要的字母)。正是這次痛苦的經(jīng)歷促使Lloyd想要寫(xiě)一個(gè)能夠幫助查找內(nèi)存泄露的工具。

內(nèi)存泄露定位工具

現(xiàn)在已經(jīng)有許多好用且不斷增強(qiáng)的工具用于定位Node.js應(yīng)用的內(nèi)存泄露。下面是其中的一些:

上面的這些工具我們都很喜歡,但是沒(méi)有一個(gè)適用于我們的場(chǎng)景。Web Inspector對(duì)于開(kāi)發(fā)中的應(yīng)用非常棒,但是很難用于熱部署的場(chǎng)景,尤其是在多服務(wù)器和涉及子進(jìn)程的時(shí)候。同樣的,在長(zhǎng)時(shí)間高負(fù)載運(yùn)行中出現(xiàn)的內(nèi)存泄露也很難復(fù)現(xiàn)。像dtrace和libumem這樣的工具雖然讓人印象深刻,但是不是所有的操作系統(tǒng)都能用。

Enternode-memwatch

我們需要一個(gè)跨平臺(tái)的調(diào)試庫(kù),當(dāng)我們的程序可能存在內(nèi)存泄漏時(shí),它不需要設(shè)備告訴我們,并且會(huì)幫我們找到哪里存在泄漏。所以我們實(shí)現(xiàn)了node-memwatch。

它給我們提供三件東西:

    一個(gè)‘泄漏'事件發(fā)射器
   

   memwatch.on('leak', function(info) {
  // look at info to find out about what might be leaking
  });

    一個(gè)‘狀態(tài)事件發(fā)射器
   
     

  var memwatch = require('memwatch');
  memwatch.on('stats', function(stats) {
  // do something with post-gc memory usage stats
  });

    一個(gè)堆內(nèi)存區(qū)分類
   

  var hd = new memwatch.HeapDiff();
  // your code here ...
  var diff = hd.end();

    并且還有一個(gè)在測(cè)試時(shí)很有用處的,可以觸發(fā)垃圾收集器的功能。好吧,一共四點(diǎn)。
   
  

 var stats = memwatch.gc();

memwatch.on('stats', ...): Post-GC堆統(tǒng)計(jì)

node-memwatch能夠在任何一個(gè)JS對(duì)象分配之前,緊隨著一次完整的垃圾回收和內(nèi)存壓縮發(fā)出一個(gè)內(nèi)存使用樣本。(它使用了V8的post-gc鉤子,V8::AddGCEpilogueCallback,來(lái)在每次垃圾回收觸發(fā)時(shí)收集堆使用信息)

統(tǒng)計(jì)數(shù)據(jù)包括:

  •     usage_trend(使用趨勢(shì))
  •     current_base(當(dāng)前基數(shù))
  •     estimated_base(預(yù)期基數(shù))
  •     num_full_gc (完整的垃圾回收次數(shù))
  •     num_inc_gc (增長(zhǎng)的垃圾回收次數(shù))
  •     heap_compactions (內(nèi)存壓縮次數(shù))
  •     min (最?。?/li>
  •     max (最大)

這里有一個(gè)展示存在內(nèi)存泄露的應(yīng)用的數(shù)據(jù)看起來(lái)是什么樣的例子。下面的圖表隨著時(shí)間追蹤內(nèi)存的使用。瘋狂的綠線展示了process.memoryUsage()報(bào)告的內(nèi)容。紅線展示了node_memwatch報(bào)告的current_base。左下側(cè)的盒子展示了附加信息。

2015623152204606.png (572×441)

 注意Incr GCs非常高。那說(shuō)明V8在拼命的嘗試清理內(nèi)存。

memwatch.on('leak', ...): 堆分配趨勢(shì)

我們定義了一個(gè)簡(jiǎn)單的偵測(cè)算法來(lái)提醒你應(yīng)用程序可能存在內(nèi)存泄漏。即如果經(jīng)過(guò)連續(xù)五次GC,內(nèi)存仍被持續(xù)分配而沒(méi)有得到釋放,node-memwatch就會(huì)發(fā)出一個(gè)leak事件。事件的具體信息格式是明了易讀的,就像這樣:
 

{ start: Fri, 29 Jun 2012 14:12:13 GMT,
 end: Fri, 29 Jun 2012 14:12:33 GMT,
 growth: 67984,
 reason: 'heap growth over 5 consecutive GCs (20s) - 11.67 mb/hr' }

memwatch.HeapDiff(): 查找泄漏元兇

最后,node-memwatch能比較堆上對(duì)象的名稱和分配數(shù)量的快照,其對(duì)比前后的差異可以幫助找出導(dǎo)致內(nèi)存泄漏的元兇。
 

var hd = new memwatch.HeapDiff();
 
// Your code here ...
 
var diff = hd.end();

對(duì)比產(chǎn)生的內(nèi)容就像這樣:
 

{
 "before": {
  "nodes": 11625,
  "size_bytes": 1869904,
  "size": "1.78 mb"
 },
 "after": {
  "nodes": 21435,
  "size_bytes": 2119136,
  "size": "2.02 mb"
 },
 "change": {
  "size_bytes": 249232,
  "size": "243.39 kb",
  "freed_nodes": 197,
  "allocated_nodes": 10007,
  "details": [
   {
    "what": "Array",
    "size_bytes": 66688,
    "size": "65.13 kb",
    "+": 4,
    "-": 78
   },
   {
    "what": "Code",
    "size_bytes": -55296,
    "size": "-54 kb",
    "+": 1,
    "-": 57
   },
   {
    "what": "LeakingClass",
    "size_bytes": 239952,
    "size": "234.33 kb",
    "+": 9998,
    "-": 0
   },
   {
    "what": "String",
    "size_bytes": -2120,
    "size": "-2.07 kb",
    "+": 3,
    "-": 62
   }
  ]
 }
}

HeapDiff方法在進(jìn)行數(shù)據(jù)采樣前會(huì)先進(jìn)行一次完整的垃圾回收,以使得到的數(shù)據(jù)不會(huì)充滿太多無(wú)用的信息。memwatch的事件處理會(huì)忽略掉由HeapDiff觸發(fā)的垃圾回收事件,所以在stats事件的監(jiān)聽(tīng)回調(diào)函數(shù)中你可以安全地調(diào)用HeapDiff方法。

相關(guān)文章

  • nodejs?express路由匹配控制及Router模塊化使用詳解

    nodejs?express路由匹配控制及Router模塊化使用詳解

    這篇文章主要為大家介紹了nodejs?express路由匹配控制及Router模塊化使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • Node.js成為Web應(yīng)用開(kāi)發(fā)最佳選擇的原因

    Node.js成為Web應(yīng)用開(kāi)發(fā)最佳選擇的原因

    本篇文章給大家詳細(xì)分析了Node.js 成為 Web 應(yīng)用開(kāi)發(fā)最佳選擇的十個(gè)原因,對(duì)此有需要的朋友參考下。
    2018-02-02
  • 如何使用?Node.js?將?MongoDB?連接到您的應(yīng)用程序

    如何使用?Node.js?將?MongoDB?連接到您的應(yīng)用程序

    NoSQL?數(shù)據(jù)庫(kù)對(duì)于處理大量分布式數(shù)據(jù)非常有用,我們可以在這個(gè)數(shù)據(jù)庫(kù)中存儲(chǔ)信息,對(duì)其進(jìn)行管理,這篇文章主要介紹了使用?Node.js?將?MongoDB?連接到您的應(yīng)用程序,需要的朋友可以參考下
    2022-09-09
  • 三行命令切換Node.js版本的流程步驟

    三行命令切換Node.js版本的流程步驟

    如何在Windows上更新Node.js版本呢?有沒(méi)有那種不需要重新安裝軟件再修改配置文件和環(huán)境變量的方法?你是否還在為可能要重新安裝Node然后配置文件修改環(huán)境變量困擾?面就來(lái)介紹一下nvm更換node版本的步驟,需要的朋友可以參考下
    2024-01-01
  • Node.js的項(xiàng)目構(gòu)建工具Grunt的安裝與配置教程

    Node.js的項(xiàng)目構(gòu)建工具Grunt的安裝與配置教程

    Grunt是為Node打造的項(xiàng)目構(gòu)建工具,相當(dāng)于C/C++世界中的makefile,可以執(zhí)行像壓縮、編譯、單元測(cè)試、代碼檢查以及打包發(fā)布的任務(wù),下面我們就來(lái)一起看一下Node.js的項(xiàng)目構(gòu)建工具Grunt的安裝與配置教程:
    2016-05-05
  • better?sqlite3安裝node?gyp原生模塊編譯prebuild-install

    better?sqlite3安裝node?gyp原生模塊編譯prebuild-install

    這篇文章主要為大家介紹了Nodejs關(guān)于原生模塊編譯node-gyp?+?prebuild-install?(以安裝?better-sqlite3為例)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Node.js中的文件系統(tǒng)(file system)模塊詳解

    Node.js中的文件系統(tǒng)(file system)模塊詳解

    Node.js文件系統(tǒng)模塊提供了豐富的方法,用于讀取、寫(xiě)入、操作文件和目錄,文件系統(tǒng)模塊是Node.js強(qiáng)大而靈活的一部分,為文件操作提供了方便的API,本文給大家介紹Node.js中的文件系統(tǒng)(file system)模塊,感興趣的朋友一起看看吧
    2023-11-11
  • 詳解如何實(shí)現(xiàn)自由切換Node.js版本

    詳解如何實(shí)現(xiàn)自由切換Node.js版本

    作為開(kāi)發(fā)者,我們經(jīng)常在不同的項(xiàng)目中需要使用不同版本的 Node.js,有時(shí)舊項(xiàng)目需要舊版本,而新項(xiàng)目則可能依賴最新的 Node.js 版本,本文將介紹幾種常用的方法來(lái)自由切換 Node.js 版本,需要的朋友可以參考下
    2024-10-10
  • nodejs實(shí)現(xiàn)發(fā)送郵箱驗(yàn)證碼功能

    nodejs實(shí)現(xiàn)發(fā)送郵箱驗(yàn)證碼功能

    這篇文章主要為大家詳細(xì)介紹了nodejs實(shí)現(xiàn)發(fā)送郵箱驗(yàn)證碼功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • 基于Node.js實(shí)現(xiàn)壓縮和解壓縮的方法

    基于Node.js實(shí)現(xiàn)壓縮和解壓縮的方法

    本篇文章主要介紹了基于Node.js實(shí)現(xiàn)壓縮和解壓縮的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02

最新評(píng)論

龙岩市| 崇明县| 灵武市| 普兰县| 日喀则市| 纳雍县| 嵩明县| 扎囊县| 贵阳市| 砀山县| 安塞县| 平乡县| 来凤县| 乾安县| 舟曲县| 卓资县| 石城县| 延安市| 房山区| 金华市| 大竹县| 沙田区| 前郭尔| 洮南市| 乌海市| 铜鼓县| 大姚县| 称多县| 延边| 洮南市| 仪征市| 比如县| 阳泉市| 阿瓦提县| 浪卡子县| 迁安市| 中超| 杨浦区| 金平| 大名县| 巧家县|