溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

nodejs垃圾回收的案例分析

發(fā)布時間:2021-01-08 11:59:00 來源:億速云 閱讀:289 作者:小新 欄目:web開發(fā)

這篇文章將為大家詳細(xì)講解有關(guān)nodejs垃圾回收的案例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

nodejs的垃圾回收機(jī)制是由v8引擎自動管理的。

nodejs的內(nèi)存限制

在一般的后端語言(php)來說,內(nèi)存的使用上是沒有限制的,但對于nodejs來說只能使用系統(tǒng)的部分----64位系統(tǒng)為1.4G,32位系統(tǒng)位0.7G。這時如果你要處理個3G文件進(jìn)行數(shù)據(jù)分析,即使系統(tǒng)的內(nèi)存為8G,在該nodejs進(jìn)程內(nèi)存還是會溢出。

造成上面這個問題主要是因為nodejs是基于v8的,nodejs是通過v8自己的方式來管理內(nèi)存的。那v8為什么要限制堆內(nèi)存的大小呢?原因有2:

1、表層原因:v8是為瀏覽器設(shè)計的,不大可能遇到大內(nèi)存的情景。

2.深層原因:v8垃圾回收機(jī)制的限制。以1.5G的堆內(nèi)存為例,v8做一次小的垃圾回收需要50ms,做一次非增量的垃圾回收要1s。垃圾回收時會引起js的線程的暫停,在這樣的時間花銷下,應(yīng)用的性能、響應(yīng)能力會直線下降。

內(nèi)存限制是可以打開的:
 --max-old-space-size(老生代)
 --max-new-space-size(新生代)
 v8堆內(nèi)存大小 = 老生代 + 新生代

v8垃圾回收機(jī)制
v8垃圾回收主要是基于分代式垃圾回收機(jī)制。按對象的存活時間將內(nèi)存的垃圾回收進(jìn)行不同的分代,分別對不同的分代內(nèi)存進(jìn)行不同的算法。

新生代--->存活時間較短的對象
老生代--->存活時間較長或常駐內(nèi)存的對象
上面也說過,nodejs堆內(nèi)存的大小是新生代內(nèi)存空間加上老生代內(nèi)存空間。

新生代算法
新生代主要是通過scavenge算法進(jìn)行垃圾回收。

這是一種采用復(fù)制的方式來實現(xiàn)垃圾回收,將堆內(nèi)存一分為二,每個空間稱為semispace。在這2個semispace空間中,只有一個處于使用中(稱為from空間),另一個處于空閑中(稱為to空間)。開始分配時首先從from空間開始,當(dāng)開始垃圾回收時,也是從from空間開始檢查存活對象,把存活對象復(fù)制到to空間,而非存活對象占用的空間就會被釋放。完成復(fù)制后,from空間和to空間角色對調(diào)。
從上面的過程可以知道,scavenge的缺點就是只使用了一半的堆內(nèi)存,犧牲空間獲取時間。

老生代通過mark-sweep、mark-comopact算法。

mark-sweep標(biāo)記清除,分為標(biāo)記、清除2個階段。mark-sweep先在標(biāo)記階段遍歷堆內(nèi)存中的所有對象,并標(biāo)記存活的對象;在清除階段把沒有被標(biāo)記的對象清除??梢钥闯?,scavenge只復(fù)制存活的對象,mark-sweep只清理死亡的對象。因為在新生代中存活的對象占用小部分,而在老生代中死亡對象占用小部分,這是這2中算法高效的原因。

Mark-compact標(biāo)記整理,mark-sweep中會出現(xiàn)一個問題,在回收后,對內(nèi)存會出現(xiàn)不連續(xù)的狀態(tài)(內(nèi)存碎片)。內(nèi)存碎片會對后續(xù)的內(nèi)存分配造成影響,因為會有這樣一種情況:需要分配個大內(nèi)存,而所有內(nèi)存碎片都無法完成分配,這會提前觸發(fā)垃圾回收,而這個回收時不必要的。Mark-compact是在Mark-sweep基礎(chǔ)上演變而來的,它主要區(qū)別在于:對象被標(biāo)記后,在整理的過程中會將存活的對象都往一端移動,移動完成后直接清除。

小結(jié):在正常的使用過程中,v8的內(nèi)存限制還是夠用的,但nodejs的垃圾回收、單線程還是會影響性能。想要高性能,需要讓垃圾回收盡量小。在實際的開發(fā)中要老生代對象的使用,如實現(xiàn)web服務(wù)的會話(session),一般會通過內(nèi)存來存儲(數(shù)組),在訪問量大的情況下會導(dǎo)致老生代對象劇增,有可能造成溢出。如果要處理大內(nèi)存的數(shù)據(jù),比如讀取3G的文件,我們會通過可讀流的pipe()方法,這樣就不會受到v8內(nèi)存的限制影響,提高了nodejs程序的健壯性。

關(guān)于“nodejs垃圾回收的案例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI