[筆記] Swift深入淺出常見語法 – Value Type vs Reference Type (about Memory)

crop person putting crumpled paper in box on woman
分享

Value Type相比Reference Type,最大的優勢在於記憶體使用的效率。Value Type是在Stack上操作,Reference Type則在Heap中。Stack上的操作僅僅是單個指標的上下移動,而Heap則牽涉到合併、移位、重新連結等。也就是說Swift這樣設計,大幅減少了Heap上的記憶體分配和回收次數,同時又將值傳遞和複製的開銷降到最低。

為了對兩者在記憶體中的表現有更深的印象,稍微複習一下Stack與Heap:

  1. Value Type與Reference Type的 “變數” 都會存放在Stack,但後者的值會放在Heap
  2. Stack為靜態記憶體配置、Heap則為動態記憶體配置
  3. Stack為固定Size,超過會造成 => Stack-overflow
  4. Heap的資源要注意Memory Leak
  5. Stack為向下、往低位址,Heap為向上、往高位址
  6. Memory中的Heap,與資料結構中的Heap沒有任何關係,只是名字剛好一樣
  7. Memory中的Stack,遵循資料結構中的Stack處理流程

由於Stack在操作上相對簡單,加上程式的編寫也跟Stack push pop 的邏輯相近,因此區域變數(return & release)與可預測的資源會被分配到Stack,並依照LIFO的方式處理 -> 靜態記憶體配置

Heap則會存放物件或不可預測的資源 -> 動態記憶體配置

Stack & Heap 範例

func hello() {
  var b = "hello"    
  // hello() stackFrame = [b],    heap = {}
  var c = "Hi".      
  // hello() stackFrame = [b, c], heap = {}
  var obj = Earth()
  // hello() stackFrame = [b, c, ref -> obj], heap = { {Object obj} }
  return // {Object obj} in heap should be released by ARC
} // hello() stackFrame = [], heap = {}

func test() {
  var test = "123"   // test() stackFrame = [test], heap = {}
  return
} // test() stackFrame = [], heap = {}

func main() {
  // sub [] in stack is stackFrame of main()
  // stack = [[]], heap = {}
  var a = 1
  // stack = [[a]], heap = {}
  hello() // stack = [[a, hello() stackFrame]], heap = {} 
  // stack = [[a]], heap = {} 
  test() // stack = [[a, test() stackFrame]], heap = {}
  // stack = [[a]], heap = {}
}
// stack = [], heap = {}

參考資料:


發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *