做者:http://blog.csdn.net/mycwq html
每一個Erlang進程建立以後都會有本身的PCB,棧,私有堆。erlang不知道他建立的進程會用到哪一種場合下,因此一開始分配的內存比較小。若是分配的空間不夠了,erlang gc會動態調整堆大小以知足需求,若是分配的空間大了,就會收縮堆,回收內存。 ide
erlang進程堆的gc是分代gc,分代gc的想法基於統計學:大部分數據的生存週期都比較短,最新的數據更容易再也不被使用。這裏erlang使 用young heap 和old heap來區分數據,young heap放新數據,old heap放舊數據,也就是gc後存活的數據。 函數
erlang進程堆gc有兩個主要過程:淺掃描和深掃描 ui
淺掃描(minor collection) spa
淺掃描是當young heap空間不足時,erlang會對young heap作一次掃描,把有用的數據複製到新申請的young heap空間,發現已經掃描過1次以上的數據放入old heap,而後刪掉原來的young heap .net
在young heap中,erlang使用了高水位線來區分標記一次以上的數據和未標記的數據,那麼young heap移入old heap的就是超太高水位線的數據 orm
深掃描(major collection) htm
深掃描是通常當old heap空間不足時觸發,erlang會對young heap和old heap作掃描,把有用的數據放入新申請的young heap,刪掉原來的heap blog
深掃描的觸發條件還有手動執行gc,和gc次數超過fullsweep_after的參數限定 生命週期
控制垃圾回收
以遊戲網關進程爲例,網關進程一般有大量消息,而大部分消息都只是在網關這裏作轉發,生命週期很短,因此網關進程能夠設定較大的初始內存,較快的內存回收。spawn_opt(Fun, [{min_heap_size, 5000},{min_bin_vheap_size, 100000},{fullsweep_after, 500}])
先看下參數默認值:min_heap_size是進程最小堆大小
這個參數兩個地方會用到,第一處是erlang初始化進程堆大小,第二處是gc後堆收縮後維持的最小值,min_bin_vheap_size是進 程最小虛擬二進制堆大小,這兩個參數都是以word爲單位。初始化足夠大的初始內存,能夠減小輕度gc的次數,減小反覆申請和回收內存的開銷
fullsweep_after控制深掃描的頻率
這個參數肯定多少次gc後執行一次深度gc,默認值爲65536,有點大了
因此,上面3個參數配合起來的意義就是,進程初始化分配足夠大的內存,減小反覆申請內存的開銷,當申請的內存不夠用,gc會從新申請內存,累計達到500次就作一次gc
手動執行垃圾回收
上面提到了利用fullsweep_after來控制gc的狀況,下面再介紹手動gc的狀況:erlang進程佔用多少內存
用下面這個方法檢查erlang進程佔用的內存,你能夠換別的參數再試試前面講到erlang進程堆的gc是分代gc的,這個只是全局層面的,在底層erlang仍是走了標記清除的路子。標記清除這種gc方式是按期執行 的,首先gc不夠及時,其次,在gc執行期間開銷比較大,會引發中斷。不過每一個erlang進程的堆區域是獨立的,gc能夠獨立進行,加上它內存區域比較 小,還有erlang的變量是單次賦值,無需屢次追蹤,所以,erlang進程gc的延遲不會引發全局的中斷
erlang文檔 參考結束語
這裏講了erlang進程堆的gc,另外erlang還有其餘gc機制,好比,二進制共享堆和進程外堆碎片是引用計數gc,這裏先不作討論,有時間我會在下篇作討論,有興趣能夠看這裏瞭解一下。
參考:
http://blog.csdn.net/mycwq/article/details/26613275
http://www.cnblogs.com/me-sa/archive/2011/11/13/erlang0014.html