標籤:
廢話片:
講到記憶體可以聯想到很多,記憶體配置管理,記憶體回收機制,記憶體泄露等等,今天我們就來答題的總結一下。
本文片:
1.記憶體配置管理
2.記憶體回收機制
3.記憶體泄露
一、記憶體配置管理
首先讓我們看看記憶體的分配機制吧。其實在所有的語言中記憶體的分配都是一樣的,首先在我們需要的時候記性記憶體的分配,然後是使用分配的記憶體,最後是當我們不適用的時候收回記憶體塊。
問題:在js中是如何分配記憶體的呢,什麼時候分配呢?
回答:在js中當我們定義了變數的時候實際上就為我們分配好了記憶體的,這樣將會省去我們的很多麻煩。了如如下:
1 // 給數值變數分配記憶體 2 var n = 123; 3 // 給字串分配記憶體 4 var s = "azerty"; 5 6 // 給對象及其包含的值分配記憶體 7 var o = { 8 a: 1, 9 b: null10 }; 11 12 // 給數組及其包含的值分配記憶體(就像對象一樣)13 var a = [1, null, "abra"]; 14 15 // 給函數(可調用的對象)分配記憶體16 function f(a){17 return a + 2;18 } 19 20 // 函數運算式也能分配一個對象21 someElement.addEventListener(‘click‘, function(){22 someElement.style.backgroundColor = ‘blue‘;23 }, false);
當然,還有其他的也寫情況實際上也是需要系統為我們分配記憶體的,例如當我們使用建構函式來定義一個新的對象的時候,我們是需要對新的對象討要空間的。
1 var d = new Date(); // 分配一個 Date 對象2 var e = document.createElement(‘div‘); // 分配一個 DOM 元素
有的時候我們需要對於資料進行組合或是在原有的資料上進行值的設定,這時系統也會為我們新分配一塊記憶體地區。
1 var s = "azerty"; 2 var s2 = s.substr(0, 3); // s2 是一個新的字串 3 // 因為字串是不變數 4 // JavaScript 可能沒有分配記憶體 5 // 但只是儲存了 [0-3] 的範圍。 6 7 var a = ["ouais ouais", "nan nan"]; 8 var a2 = ["generation", "nan nan"]; 9 var a3 = a.concat(a2); 10 // 新數組有四個元素,是 a 串連 a2 的結果
問題:記憶體空間使用?
回答:當系統為我們分配了記憶體空間之後我們實際上在每一次對於當前的值得操作的時候都是使用了這一記憶體塊,讀取和寫入操作將會是我們對於記憶體塊的基礎操作。
二、記憶體回收機制
問題:js的記憶體是如何回收的?
回答:js是具有自動垃圾收集機制的,這種機制會自動的跟蹤每一個變數的動向,並判斷當前的變數是否還有存在的必要,然後將不必要的變數所佔用的記憶體進行收回。對於這樣的收回機制,實際真正的運用起來是有兩種不同的方法來實現的。詳情見如下:
1.方法一:標記清除演算法
這一演算法是為進入環境中的變數標記一個“進入環境”的標記。邏輯上講呢,當我們的變數進入環境的時,變數實際上是不應該被刪除的,因為上下文中可能會用到當前的變數進行相關的邏輯演算,而當變數離開環境的時候,竟會為其標記成為“離開環境”的狀態。
2.方法二:引用計數
其寓意在於耿總記錄每一個變數的調用的次數。當變數的計數次數便成為0的時候其實也就是說明我們將不會是在方位當前的變數了,這時候就是需要把記憶體空間收回的時候了。
以上其實就是最為常用的記憶體回收機制,當然我們的記憶體回收機制是在一定的時間間隔後,自動的啟動並執行,每次都會搜尋是否有變數可以收回,並回收記憶體。
三、記憶體流失
記憶體流失是指在我們編碼的過程中,有的某一些操作是的當前的記憶體塊即使不在會被使用到,釋放機制也因為辨別不出(bug啦)是否需要釋放而使得這一不需要的變數得以保留。雖然對於有記憶體回收機制的js和java是很少有這種情況發生的。但是。。。你懂得,下面就來看一看有哪些情況會導致這一情況
1、當我們在IE中使用.onclick的時候如果我們沒有手動的刪除這一事件則會造成和記憶體流失(IE果然好坑啊)
1 document.getElementById("xxx").onclick = fuction(){}; 2 //在IE中是不會自動的回收記憶體的。 3 4 //改進方法 5 document.getElementById("xxx").onclick = fuction(){ 6 document.getElementById("xxx").onclick = null; 7 ....... 8 }; 9 10 //或者使用11 document.getElementById("xxx").addEventListener(......);
2、當我們對於DOM對象使用循環參考的情況下,js的回收機制就沒有辦法回收了。
1 var a = document.getElementById("xxx");2 a.r = a;
3、必報在編寫過程中的時候是經常要使用到的一個概念。但是但我們在閉包中定義了回應時間的時候就會造成一定量的記憶體佔用。
1 function bindEvent() 2 { 3 var obj=document.createElement("XXX"); 4 obj.onclick=function(){ 5 //Even if it‘s a empty function 6 } 7 }//這樣閉包內的obj元素回因為其中的onclick時間的綁定而沒有辦法進行釋放,這樣就造成了運行時的記憶體浪費。
4、某些代碼不嚴謹可能導致記憶體流失
1 a = {p: {x: 1}};2 b = a.p;3 delete a.p;//a中的元素實際上已已經刪除了,可是被刪除的元素並沒有清空,因為外部中變數b指向了這一元素資料。這樣就可能造成記憶體的浪費
5、最後,我們在來黑IE一把,實際上在IE中有一些DOM操作或者是屬性轉化的操作會造成相關的記憶體流失的風險,所以說我們在編寫適配IE瀏覽器的時候還是要更為的注意一些的啊。
記憶體流失的情況絕對不僅僅是我上面說的著一些,在我們的平時編寫代碼的過程中我們可以找到更多的這樣的bug並對其進行相關的最佳化,將會使得我們的代碼更為的良好而健壯。
JS記憶體知識點匯總