【JS檔案揭秘】第一集 內存泄漏與垃圾回收


程序的運行需要內存,對於一些需要持續運行很久的程序,尤其是服務器進程,如果不及時釋放掉不再需要的內存,就會導致內存堆中的占用持續走高,最終可能導致程序崩潰。

不再需要使用的內存,卻一直占用着空間,得不到釋放,這就叫內存泄漏

在JS中,我們都知道,基本數據類型是存在棧(stack)中,而引用數據類型是存在堆(heap)中。存在棧中的數據,會被自動處理掉。但存在堆中的數據則不然。

JS引擎有個垃圾回收機制,可以幫助我們來清除不需要的數據。關鍵來了,我們怎么告訴JS引擎這個我不再需要這個數據呢?

答案就是:切斷它的引用,讓它變成一座無法到達的島嶼

這就是所謂的“標記清除”。也就是說,我們對堆中的引用類型數據做一個遍歷,標記一下它們是否是可以被外部訪問到的:

let a = {name:'zhang'};
let b = a;

let c = {name:'zhao'};
c = null;

在上面的這段代碼中,{name:'zhang'}這個對象分別被變量a和變量b引用。{name:'zhao'}這個對象一開始被變量c引用,后來c被重新賦值,{name:'zhao'}這個對象的引用突然被切斷,再也無法被訪問到了,自己變成了一個“孤島式數據”,無法被外部訪問,被當成了垃圾。

 

而垃圾的宿命,就是被JS引擎回收。

我們來執行一下上述這段代碼,每點擊一次,就給obj存入1000個不同對象的引用,連續點擊10s,停止30s。並把這個過程錄制下來。

怎么錄?打開chrome的performance即可錄制,看看這40s的內存堆(JS heap)的走勢。

 

 (結果是令人寒心的,堆內存占用從15M左右飆到最高30M,且基本沒有什么回落,居高不下)

 

現在我們把代碼改一改,在末尾增加一句this.obj = []。用於清除本次操作產生的1000個引用。

按照同樣的手法,點擊10s,停止30s,總共錄制40s。效果如下:

(可以看到中途最高飆到24.7M,但是垃圾回收在第5s和第10s都介入了一次,使得內存占用大幅減少)

 

可以看到垃圾回收還是很有用的,同時也可以看到,垃圾回收並不是無時無刻都在進行,因為垃圾回收這個操作也有性能損耗,從我實測的結果來看,它是按照一定的時間間隔進行的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM