Node之內(nèi)存管理

V8的垃圾回收機(jī)制與內(nèi)存限制

一般的后端開(kāi)發(fā)語(yǔ)言中,基本的內(nèi)存使用上沒(méi)有什么限制吏饿,然而在Node中通過(guò)Javascript使用內(nèi)存時(shí)就會(huì)發(fā)現(xiàn)只能使用部分內(nèi)存(64位系統(tǒng)中約為1.4GB捏卓,32位系統(tǒng)中約為0.7GB)丛忆。這樣限制,會(huì)導(dǎo)致2GB的文件讀取內(nèi)存無(wú)法進(jìn)行字符串分析處理盖袭,即使物理內(nèi)存有32GB失暂,在Node單進(jìn)程中,計(jì)算機(jī)的內(nèi)存資源無(wú)法得到充分的使用苍凛。

背后核心的問(wèn)題在于Node基于V8構(gòu)建趣席,Node中使用的JS對(duì)象基本上都是通過(guò)V8的方式分配和管理,V8在瀏覽器足夠使用醇蝴,但是在后臺(tái)服務(wù)器開(kāi)發(fā)中卻無(wú)法滿足需求宣肚。

查看內(nèi)存使用情況

node 
precess.memoryUsage()

V8的垃圾回收機(jī)制

V8的垃圾回收算法

主要是基于分代垃圾回收機(jī)制,現(xiàn)在的垃圾回收算法中按照對(duì)象的存活事件將內(nèi)存的垃圾回收進(jìn)行不同的分代悠栓,然后對(duì)不同分代的內(nèi)存施以更高效的算法霉涨。

  • V8的內(nèi)存分代

    主要將內(nèi)存分為新生代和老生代兩代。新生代中的對(duì)象位存活時(shí)間較短的對(duì)象惭适,老生代中的對(duì)象位存活時(shí)間較長(zhǎng)或者常駐內(nèi)存的對(duì)象笙瑟。

    內(nèi)存的設(shè)置需要在Node啟動(dòng)的時(shí)候設(shè)置,無(wú)法動(dòng)態(tài)改變

    --max-new-space-size  1024 單位MB
    --max-old-space-size  1024 單位KB
    

    默認(rèn)設(shè)置下癞志,在64位系統(tǒng)和32位系統(tǒng)下只能使用越1.4GB和約0.7GB的大小

  • Scavenge算法

    在分代的基礎(chǔ)上往枷,新生代中的對(duì)象主要通過(guò)Scanvenge算法進(jìn)行垃圾回收,具體是一種采用復(fù)制的方式實(shí)現(xiàn)的垃圾回收算法凄杯,它將堆內(nèi)存一分為二错洁,兩個(gè)空間,只有一個(gè)處于使用中戒突,另外處于閑置狀態(tài)屯碴,處于使用狀態(tài)的空間位From空間,處于閑置狀態(tài)的空間稱(chēng)為T(mén)o空間膊存。當(dāng)分配對(duì)象時(shí)导而,首先在From空間進(jìn)行分配,當(dāng)開(kāi)始進(jìn)行垃圾回收隔崎,會(huì)檢查From空間中的存活對(duì)象今艺,存活對(duì)象將被復(fù)制到To空間,非存活對(duì)象占用的空間將會(huì)被釋放爵卒。完成復(fù)制后虚缎,F(xiàn)rom空間和To空間的角色進(jìn)行兌換。

    Scavenge的缺點(diǎn)是只能使用堆內(nèi)存中的一半技潘,典型的犧牲了空間換取時(shí)間的算法遥巴,非常適合新生代對(duì)象的生命周期較短。

    當(dāng)一個(gè)對(duì)象經(jīng)過(guò)多次復(fù)制依然存活享幽,它將會(huì)被認(rèn)為是生命周期較長(zhǎng)的對(duì)象铲掐,隨后會(huì)被移動(dòng)到老生代中

  • Mark-Sweep & Mark-Compact

    對(duì)于老生代中的對(duì)象,由于存活對(duì)象占較大比重值桩,所以采用標(biāo)記清楚摆霉,分為標(biāo)記和清除兩個(gè)階段,在標(biāo)記階段遍歷堆中的雖有對(duì)象奔坟,并標(biāo)記活著的對(duì)象携栋,在隨后的清除階段,只清除沒(méi)有被標(biāo)記的對(duì)象咳秉。為了解決清除后出現(xiàn)的內(nèi)存碎片問(wèn)題婉支,出現(xiàn)Mark-Compact

    回收算法 Mark-Sweep Mark-Compact Scavenge
    速度 中等 最慢 最快
    空間開(kāi)銷(xiāo) 少(碎片) 少(無(wú)碎片) 雙倍空間(無(wú)碎片)
    是否移動(dòng)對(duì)象

    ?

高效使用內(nèi)存

作用域

  1. JS的作用域只有函數(shù)調(diào)用,以及全局作用域

  2. 函數(shù)調(diào)用

    函數(shù)在每次被調(diào)用會(huì)創(chuàng)建對(duì)象的作用域澜建,函數(shù)執(zhí)行結(jié)束向挖,該作用域?qū)?huì)銷(xiāo)毀,同事作用域中聲明的局部變量分配在該作用域上炕舵,隨著作用域的銷(xiāo)毀而在下次垃圾回收時(shí)被釋放

  3. 變量的主動(dòng)釋放

    如果變量私全局變量何之,由于全局作用域需要直接到進(jìn)程退出才能釋放,此時(shí)將導(dǎo)致引用的對(duì)象常駐內(nèi)存咽筋,此時(shí)如果需要釋放常駐內(nèi)存的對(duì)象溶推,可以將變量重新賦值null defined即可,接下來(lái)的老生代內(nèi)存清楚和整理的過(guò)程中奸攻,會(huì)被回收釋放蒜危。

  4. 閉包

    閉包的使用會(huì)導(dǎo)致,一旦變量引用了這個(gè)中間函數(shù)舞箍,這個(gè)中間函數(shù)就不會(huì)釋放舰褪,同時(shí)也會(huì)使原始的作用域不會(huì)得到釋放,除非不再引用疏橄,才會(huì)逐步釋放占拍。

內(nèi)存的劃分

  • 棧內(nèi)內(nèi)存

    主要是通過(guò)V8的劃分獲得 主要受V8引擎的限制。

  • 堆外內(nèi)存

    主要是Stream Buffer之類(lèi)的需要處理二進(jìn)制的數(shù)據(jù) 在堆外劃分捎迫,主要是受操作系統(tǒng)的進(jìn)程常駐內(nèi)存晃酒。

大內(nèi)存應(yīng)用

Node主要提供了stream模塊用于處理大文件

stream模塊是Node的原生模塊, stream繼承EventEmitter窄绒,對(duì)于大文件我們無(wú)法通過(guò)fs.readFile()和fs.writeFile()直接進(jìn)行大文件的操作贝次,可以通過(guò)改用流的方式對(duì)大文件的操作

var reader = fs.createReadStream('in.txt')
var writer = fs.createWriteStream('out.txt')
reader.pipe(writer);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市彰导,隨后出現(xiàn)的幾起案子蛔翅,更是在濱河造成了極大的恐慌敲茄,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件山析,死亡現(xiàn)場(chǎng)離奇詭異堰燎,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)笋轨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)秆剪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人爵政,你說(shuō)我怎么就攤上這事仅讽。” “怎么了钾挟?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵洁灵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我掺出,道長(zhǎng)处渣,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任蛛砰,我火速辦了婚禮罐栈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘泥畅。我一直安慰自己荠诬,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布位仁。 她就那樣靜靜地躺著柑贞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪聂抢。 梳的紋絲不亂的頭發(fā)上钧嘶,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音琳疏,去河邊找鬼有决。 笑死,一個(gè)胖子當(dāng)著我的面吹牛空盼,可吹牛的內(nèi)容都是我干的书幕。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼揽趾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼台汇!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤苟呐,失蹤者是張志新(化名)和其女友劉穎痒芝,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體牵素,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡吼野,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了两波。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡闷哆,死狀恐怖腰奋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情抱怔,我是刑警寧澤劣坊,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站屈留,受9級(jí)特大地震影響局冰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜灌危,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一康二、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧勇蝙,春花似錦沫勿、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至翁锡,卻和暖如春蔓挖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背馆衔。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工瘟判, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人角溃。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓荒适,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親开镣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子刀诬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 使用JavaScript進(jìn)行前端開(kāi)發(fā)時(shí)幾乎完全不需要關(guān)心內(nèi)存管理問(wèn)題,對(duì)于前端編程來(lái)說(shuō),V8限制的內(nèi)存幾乎不會(huì)出現(xiàn)...
    寫(xiě)B(tài)log不取名閱讀 10,863評(píng)論 9 20
  • 本文引用自這里這篇文章的所有內(nèi)容均來(lái)自 樸靈的《深入淺出Node.js》及A tour of V8:Garbage...
    楠小忎閱讀 1,409評(píng)論 0 2
  • 第一章 簡(jiǎn)介 J2SE平臺(tái)的一大優(yōu)勢(shì)是它的自動(dòng)化內(nèi)存管理陕壹,避免了開(kāi)發(fā)者去面對(duì)內(nèi)存管理的復(fù)雜性质欲。 本文以Sun J2...
    tianyiliusha閱讀 945評(píng)論 0 1
  • 1.什么是垃圾回收? 垃圾回收(Garbage Collection)是Java虛擬機(jī)(JVM)垃圾回收器提供...
    簡(jiǎn)欲明心閱讀 89,392評(píng)論 17 311
  • JS在瀏覽器中運(yùn)行的時(shí)候并不存在太大的內(nèi)存問(wèn)題糠馆,我們通常也不刻意的去優(yōu)化他們嘶伟,但是當(dāng)運(yùn)行在服務(wù)器端的時(shí)候,運(yùn)行時(shí)間...
    exialym閱讀 2,089評(píng)論 0 6