Go語言變數的生命週期

無鞋童鞋發表於2017-11-02

1 變數的生命週期  
  生命週期是指程式執行過程中變數存在的時間段。下面我們分別來看看包變數(全域性變數)和區域性變數兩種變數的生命週期。
  ① 包變數一直常駐在記憶體到程式的結束,然後被系統垃圾回收器回收。也就是說包變數的生命週期是整個程式的執行時間。
  ② 區域性變數,例如一個函式中定義的變數。它有一個動態的生命週期:每次執行生命語句時建立一個新的實體,變數一直生存到它變得不可訪問(例如沒有外部指標指向它,函式退出我們沒有路徑能訪問到這個變數),這時它佔用的儲存空間就會被回收。
  所以我們有結論:
  並不是定義在函式內部的區域性變數在訪問退出函式後就會被回收!
2 堆與棧的分配
  學過其他諸如C/C++語言的都知道,變數定義完成一般是分配在堆和棧空間上的。存在哪個空間上是跟你是否動態分配記憶體有關(new/malloc)。但是在Go語言上這個選擇並不是基於使用var和new關鍵字來宣告變數的。
  我們看下面兩個程式例項:

var p *int    //全域性指標變數
func f(){
    var i int
    i = 1
    p = &x    //全域性指標變數指向區域性變數i
}
func f(){
    p := new(int) //區域性指標變數,使用new申請的空間
    *p = 1
}

  上面程式中,第一個程式雖然i是通過var申請的區域性變數,但是由於有外部指標指向訪問,我們有路徑可找到這個空間(變數能夠逃逸出函式),所以區域性變數i是申請在堆空間上。而第二個程式中p指標變數雖然是使用new申請的空間,但是由於退出函式就沒有路徑可尋找到它(變數無法逃出函式),所以區域性變數p是申請在棧空間上的。
  另外我需要提的一點,Go語言區別於C/C++,雖然變數申請在堆空間上,但是它有自動回收垃圾的功能,所以這些堆地址空間也無需我們手動回收,系統會在需要釋放的時刻自動進行垃圾回收。

相關文章