首先,咱們須要對內存管理概念有一個基本的認識。內存管理是指操做系統如何進行內存的分配和回收的機制。早期的計算機語言,好比C, 它經過malloc, free函數來向操做系統請求內存和釋放內存。優勢是內存分配和釋放的效率很高;缺點主要表如今對於複雜的系統,存在着大量的內存分配和釋放操做。程序員很容易不當心忘記釋放內存,從而形成內存的泄露,對於長期運行的軟件來說,系統的內存會逐漸被吃光。 所以,更新的編程語言,好比JAVA, C#, 都提供了所謂「垃圾回收的機制」,運行時自身會運行相應的垃圾回收機制。程序員只須要申請內存,而不須要關注內存的釋放。垃圾回收器(GC)會在適當的時候將已經終止生命週期的變量的內存給釋放掉。(https://www.zhihu.com/question/19831128/answer/13097702)html
幾種垃圾回收機制算法程序員
1.引用計數算法(Reference Counting)算法
每一個對象計算指向它的指針的數量,當有一個指針指向本身時計數值加1;當刪除一個指向本身的指針時,計數值減1,若是計數值減爲0,說明已經不存在指向該對象的指針了,因此它能夠被安全的銷燬了。算法特色:1)須要單獨的字段存儲計數器,增長了存儲空間的開銷;2)每次賦值都須要更新計數器,增長了時間開銷;3)垃圾對象便於辨識,只要計數器爲0,就可做爲垃圾回收;4)及時回收垃圾,沒有延遲性;5)不能解決循環引用的問題。編程
在低版本IE中常常會出現內存泄露,不少時候就是由於其採用引用計數方式進行垃圾回收。好比對象A有一個屬性指向對象B,而對象B也有有一個屬性指向對象A,這樣相互引用瀏覽器
function test(){ var a={}; var b={}; a.prop=b; b.prop=a; }
a和b的引用次數都是2,即便在test()執行完成後,兩個對象都已經離開環境,在標記清除的策略下是沒有問題的,離開環境的就被清除,可是在引用計數策略下不行,由於這兩個對象的引用次數仍然是2,不會變成0,因此其佔用空間不會被清理,若是這個函數被屢次調用,這樣就會不斷地有空間不會被回收,形成內存泄露。安全
2. 標記-清除(Mark-Sweep)算法編程語言
Mark-Sweep依賴於對全部存活對象進行一次全局遍從來肯定哪些對象能夠回收,遍歷的過程從根出發,找到全部可達對象,除此以外,其它不可達的對象就是垃圾對象,可被回收。整個過程分爲兩個階段:標記階段找到全部存活對象;清除階段清除全部垃圾對象。Lua就採用了mark-sweep的垃圾回收機制。大部分瀏覽器也都是使用這種方式進行垃圾回收,區別在於如何標記及垃圾回收間隔而已 。函數
優勢:性能
相比較引用計數算法,標記-清除算法能夠很是天然的處理環形引用問題,spa
另外在建立對象和銷燬對象時時少了操做引用計數值的開銷
缺點:
標記-清除算法是一種「中止-啓動」算法,在垃圾回收器運行過程當中,應用程序必須暫時中止
標記-清除算法在標記階段須要遍歷全部的存活對象,會形成必定的開銷
在清除階段,清除垃圾對象後會形成大量的內存碎片。
3. 標記-縮並算法(解決內存碎片)
整個過程能夠描述爲
* 標記全部的存活對象;
* 經過從新調整存活對象位置來縮並對象圖;
* 更新指向被移動了位置的對象的指針。
標記-壓縮算法最大的難點在於如何選擇所使用的壓縮算法,若是壓縮算法選擇很差,將會致使極大的程序性能問題,如致使Cache命中率低等。通常來講,根據壓縮後對象的位置不一樣,壓縮算法能夠分爲如下三種:
任意:移動對象時不考慮它們原來的次序,也不考慮它們之間是否有互相引用的關係。
線性:儘量的將原來的對象和它所指向的對象放在相鄰位置上,這樣能夠達到更好的空間局部性。
滑動:將對象「滑動」到堆的一端,把存活對象之間的自由單元「擠出去」,從而維持了分配時的原始次序。
4. 節點拷貝算法(解決內部碎片)
節點拷貝算法是把整個堆分紅兩個半區(From,To), GC的過程其實就是把存活對象從一個半區From拷貝到另一個半區To的過程,而在下一次回收時,兩個半區再互換角色。在移動結束後,再更新對象的指針引用
參考 http://blog.csdn.net/sinat_36246371/article/details/53002209
垃圾回收器週期性運行,若是分配的內存很是多,那麼回收工做也會很艱鉅,肯定垃圾回收時間間隔就變成了一個值得思考的問題。IE6的垃圾回收是根據內存分配量運行的,當環境中存在256個變量、4096個對象、64k的字符串任意一種狀況的時候就會觸發垃圾回收器工做,看起來很科學,不用按一段時間就調用一次,有時候會不必,這樣按需調用不是很好嗎?可是若是環境中就是有這麼多變量等一直存在,如今腳本如此複雜,很正常,那麼結果就是垃圾回收器一直在工做,這樣瀏覽器就無法兒玩兒了。
微軟在IE7中作了調整,觸發條件再也不是固定的,而是動態修改的,初始值和IE6相同,若是垃圾回收器回收的內存分配量低於程序佔用內存的15%,說明大部份內存不可被回收,設的垃圾回收觸發條件過於敏感,這時候把臨街條件翻倍,若是回收的內存高於85%,說明大部份內存早就該清理了,這時候把觸發條件置回。這樣就使垃圾回收工做職能了不少。
同C# 、Java同樣咱們能夠手工調用垃圾回收程序,可是因爲其消耗大量資源,並且咱們手工調用的不會比瀏覽器判斷的準確,因此不推薦手工調用垃圾回收。
轉自http://www.cnblogs.com/dolphinX/p/3348468.html