今天總結下js的回收機制。前端
提及js的回收機制,必定要先說js的內存分配了。瀏覽器
前端的同窗們確定知道,js的變量分爲基本類型和引用類型。安全
爲何內存還要區分堆內存和棧內存呢?這裏就要說到js的垃圾回收機制了。閉包
爲何會有垃圾回收呢?固然是爲了使程序運行時的內存最小啦。性能
當一個方法執行的時候,會有部份內存用來存方法中聲明的變量,這些變量都被存在棧內存中,當方法結束的時候,這個棧內存中的變量(除了地址之外)都會被銷燬。優化
可是當咱們聲明一個對象的時候,這個對象在其餘地方也被引用了,這個對象的大小是不固定的,會被分配到堆內存中,隨着方法的結束,這個堆內存也不會被銷燬,由於其餘地方還在引用(方法的傳參等等),除非這個對象的引用爲0,垃圾回收機制纔會在覈實以後銷燬他,這裏就牽扯到了垃圾回收中的引用計數,下面會講到。操作系統
內存聲明週期:線程
在js中,第三部分是自動完成的,由於js中有自動垃圾回收機制。在編寫js時,不須要關心內存的使用問題,所需內存的分配和內存的釋放都是自動完成的。對象
什麼狀況下會內存泄漏?能夠這麼理解,就是有些代碼原本應該要被回收的,可是沒有被回收,因此一直佔用着操做系統的內存,從而越積越多。通常的內存泄漏其實可有可無,可怕的是內存泄漏引發的堆積,致使GC一直沒辦法使用所佔用的內存給其餘程序使用。遞歸
內存溢出就是程序向系統申請必定大小的內存,可是系統知足不了。
處於安全的考慮,通常狀況下系統給瀏覽器的內存會比給客戶端的內存要少,即便瀏覽器內存泄漏了或者內存溢出了也不會讓系統崩潰。內存限制的問題不只會影響到給變量分配的內存,也會影響每一個線程最多能執行的語句數量。
因此爲了確保在有限的內存中可讓頁面得到最好的性能,優化內存佔用的最佳方式就是將其值設置爲null來釋放其引用。這個方法叫作解除引用,適用於全局變量和全局對象的屬性,局部變量在離開執行環境以後就會自動被解除引用。
解除引用並不意味着立刻回收該值所佔用的內存,解除引用的真正做用是讓值離開執行環境,讓GC下次運行時自動將其回收。
js的垃圾回收通常有兩種,標記清除和引用計數。
GC在運行時會給儲存在內存中的全部變量加上標記,而後會去掉環境中的變量和被環境中的變量引用的變量的標記,在此以後被加上標記的變量被視爲要刪除的變量。而後GC完成內存清除。
標記清除會遵循如下幾種狀況:
當對象被引用次數爲0時,就被回收。潛在的一個問題是:循環引用時,兩個對象都至少被引用了一次,將不能自動被回收。因此致使,咱們常講的內存泄露。