Garbage Collection 介紹

作者 Jason Chuang 日期 2019-07-18
Garbage Collection 介紹

前陣子對golang中的回收機制突然有興趣,因為golang再回收機制上面我自己在run service時
回收的速度特別有感觸,所以研究了一下,並且稍微紀錄一些小筆記跟大家分享

What is GC?

GC 是Garbage Collection 的簡稱,中文稱為“垃圾回收”。
那在GC裡面什麼定義為“垃圾”?

把分配到堆中那些不能通過程序引用的對象稱為非活動對象,也就是死掉的對象,我們稱為“垃圾”。

What is GC doing ?

而GC主要工作就做兩件事情

1.找到內存空間裡的垃圾。
2.回收垃圾,讓程序員能再次利用這部分空間。

Heap And Stack

講到golang如何選擇哪些是”垃圾“,就不免談到 heap 與 stack的關係
簡單來說, stack 在大陸翻譯都叫做“堆”, 而heap 則稱“棧”, 不要問我為什麼因為我也不知道
在這邊就直接以原文來介紹這兩個的關係。

  • stack 主要用於靜態記憶體配置,也就是你可以預期收回的空間都會存放於 stack
  • heap 則是主要用於動態記憶體配置,是無法預期或者不能確定此空間大小則會放於 heap 上 用此程式碼來介紹說, 在StudentRegister中 我new了一個Student struct 的空間, 但因為在這個情況下, 程式會認為這個宣告沒有一個明確的收回以及空間的宣告,這時就會將這個s 配置的空間放於heap底下。 p.s. 因為stack能存放的空間是有一定大小的,因此遇到不確定的空間宣告時,程式會將這些空間放在heap 下才不怕記憶體爆炸!! 而另外main再呼叫StudentRegister時,可以明確知道main執行完後就會收回,因此程式則會將他放於stack中 golang 有個方便的參數 `-gcflags=-m` 這參數可以幫我檢查宣告的物件是否跑至heap或存於stack中

If we don’t have GC

如果沒有GC, 工程師們就得自行做內存管理,也就是上面我介紹的你不只要做好stack的回收
並且你也需要將所有跑至heap的空間管理好,否則service 跑著跑著就會記憶體不夠。
這不打緊,更怕的是可能會有收錯的問題,更嚴重可能會有重複宣告空間,講這麼多大概有感覺的GC
的重要了吧。

GC introduction

mark-sweep

  1. 會先從根路徑往下尋找所有的得達到的節點
  2. 將這些節點做標記
  3. 全部標記完後,將會STW(stop the world)
  4. 將其他沒有標記到的節點做刪除
  5. Start the world

缺點:

  1. The larger the memory, the longer the scan.
  2. Stop The World.

reference counting

  1. 任何只要一被宣告的空間就給他個一計數器(count)
  2. 若有人引用此空間count則會加一,反之取消引用則減一
  3. 當count為0時,代表無人引用,此時即可將空間給收回

缺點:

  1. Need to refer to the counting field.
  2. Can not directly deal with ring garbage.

copying

  1. 會將記憶體分為 from and to 兩個空間
  2. 當空間不足分配新對象或者定時需要收取時,則會觸發GC,做STW
  3. 此時就會將所有存活的對象全部複製到to空間下
  4. 當複製完成後再將from 和 to 的空間互換

缺點:

  1. Only half of the memory can be used at a time.
  2. The larger the memory, the longer it will scan and move.
  3. Pause the app for a long time.

小結

對於各種的GC方式先做個簡單的介紹,之後會再介紹golang使用的GC機制是怎麼樣的
但總歸一句,我能活在GC發明後的時代真是太好了(因為我是個很懶惰的人)!