js中的垃圾回收機制

 

1. 作用

JS的垃圾回收機制是爲了以防內存泄漏,內存泄漏的含義就是當已經不需要某塊內存時這塊內存還存在着,垃圾回收機制就是間歇的不定期的尋找到不再使用的變量,並釋放掉它們所指向的內存。

2.JS垃圾回收方式

方式一:標記清除(最常用的垃圾收集方式) 

      javascript中最常用的垃圾收集方式就是標記清除。當變量進入環境時,會標記爲"進入環境",而當變量離開環境時,會標記爲"離開環境"。垃圾收集器運行時會給所有存儲在內存中的變量都加上標記,然後它會去掉環境中的變量以及被環境中的變量引用的變量的標記。而再次之後在被標記的變量就是被視爲準備刪除的變量,因爲環境中的變量已經無法訪問到這些變量了。最後,垃圾收集器完成內存清除工作,銷燬那些帶着標記的值並且回收它們所佔用的內存空間。

方式一:引用計數(不常見)

      引用計數的含義是跟蹤每個值被引用的次數。當聲明瞭一個變量並將一個引用類型賦值給該變量時,則這個值的引用次數爲1.如果同一個只又被賦給另一個變量,則該值的引用次數加1。當這個值的引用次數爲0時,則說明沒有辦法再訪問這個值了,就可以將空間回收。(我們知道IE中有一部分對象並不是原生的js對象,例如BOM,DOM中的對象就是使用C++以COM對象的形式實現的,而COM對象的垃圾收集機制就是引用計數策略,所以即便IE的js引擎是已使用標記清除來實現的,但是js訪問的COM對象依然是基於引用計數策略,也就是說,只要在IE的中涉及COM對象,就會存在循環引用的問題)

循環引用:由於引用技術採用的是引用計數的方法,如果兩個對象相互引用,則引用計數都是2,執行完以後還將繼續存在,引用次數永遠不會是0。

3.性能問題

垃圾收集器都是週期性運行的,而且如果爲變量分配的內存數量很客觀,那麼回收工作量也是相當大的。在這種情況下,確定垃圾收集的時間間隔是一個非常重要的問題。說到垃圾收集器多長時間運行一次,不禁讓人聯想到IE因此聲名狼藉的性能問題。IE的垃圾收集器是根據內存分配量運行的,具體一點說就是256個變量、4096個對象(或數組)字面量和數組元素(slot)或者64KB的字符串。達到上述任何一個臨界值,垃圾收集器就會運行。這種實現的問題在於,如果一個腳本中包含那麼多變量,那麼該腳本很可能會在其生命中起一支保持那麼多的變量。而這樣一來,垃圾收集器就可能不得不頻繁的運行。結果,由此引發的嚴重性能問題初始IE7重寫了其垃圾收集例程。

隨着IE7的發佈,其javascript引擎的垃圾收集例程改變了工作方式:觸發垃圾收集的變量分配、字面量和(或)數組元素的臨界值被調整爲動態修正。IE7中的各項臨界值在初始化時與IE6相等。如果例程回收的內存分配量低於15%,則變量 、字面量和(或)數組元素的臨界值就會加倍。如果例程回收了85%的內存分配量,則將各種臨界重置會默認值。這一看似簡單的調整,極大地提升了IE在運行包含大量javascript的頁面時的性能。

事實上,在有的瀏覽器中可以觸發垃圾收集過程,當我們不建議讀者這樣做。在IE中,調用window.CollectGarbage()方法會立即指向垃圾收集,在Opera7及更高版本中,調用widnow.opera.collect()也會啓動垃圾收集例程。

4.管理內存

使具備垃圾收集機制的語言編寫程序,開發人員一般不必操心內存管理的問題。但是,javascript在進行內存管理及垃圾收集時面臨的問題還是有點與衆不同。其中最重要的一個問題,就是分配給web瀏覽器的可使用內存數量通常要比分配給桌面應用程序的少。這樣做的目的出要是處於安全方面的考慮,目的是防止運行javascript的網頁耗盡全部系統內存而導致系統崩潰。內存限制問題不僅會影響給變量分配內存,同時還會影響調用棧以及在一個線程中能夠同時執行語句數量。

因此,確保佔用最少內存可以讓頁面獲得更好的性能,最好通過將其值設置爲null來釋放其引用——這個做法叫做解除引用(dereferencing)。這一做法是用於大多數全局變量和全局對象的屬性。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章