Swift 語法日記 - 記憶體管理
Swift記憶體管理Swift當中,引用類型(class)儲存在(棧)stack上,而值類型(enum, struct)儲存在(堆)裡面,而這兩個的定義為 stack系統自動分配之記憶體,空間較小但運行較快,遵循LIFO原則,透過移動stack尾端的指針去實現pop與push操作 在執行一個方法需要在stack上為此方法開闢新的記憶體空間,stack的尾針指向stack底端移動 當執行完畢之後再將指針移回stack頂端釋放掉這些空間.
Swift記憶體管理
Swift當中,引用類型(class)儲存在(棧)stack上,而值類型(enum, struct)儲存在(堆)裡面,而這兩個的定義為
stack
系統自動分配之記憶體,空間較小但運行較快,遵循LIFO原則,透過移動stack尾端的指針去實現pop與push操作
在執行一個方法需要在stack上為此方法開闢新的記憶體空間,stack的尾針指向stack底端移動
當執行完畢之後再將指針移回stack頂端釋放掉這些空間.
heap
相較stack有較大的空間,但運行也相對的較慢,優點在於可以動態分配,不像stack中調用完直接回收
系統會在heap上尋找不再需要的記憶體(Swift中使用了ARC來幫我們處理),再多線程環境下,多線程會共享heap上的記憶體
為了確保線程安全,必須在heap上進行加鎖操作,但這動作相對浪費效能.
以一個範例來做說明
首先是我們定義一個值類型的struct並實現它
struct
ValueType
var
Double
}
let
=
ValueType
3
4
var
=
value1與value2會在stack上各分配到一塊記憶體,這兩者的儲存是獨立的,意思是你不必擔心兩者會互相影響
例如下面我們修改了value2的值,然後再去印出value1的值來觀察
value2.a =
100
print
可以發現印出來的依然是value1原來的值3.0
再來我們用class再來定義一次試試
class
ValueType
var
Double
init
a
Double
b
Double
self
=
self
=
}
}
let
=
ValueType
3
4
由於這次ValueType是class因此並不會直接將資料存在stack上,而是在stack上開闢兩個指針
由這兩個指針負責去尋找被儲存在heap上的資料,而當我們指定
var
=
value2的指針就會跟value1的指針指向同一位置,因此我們可以知道,在引用類型的賦值並不會發生拷貝的動作
所以當你修改value2的內容時也會導致指向同一位置的value1一同變動.
p.s.在這裡我們使用了let關鍵字來定義value1,限制它為一不可變動的值,但在引用類型中,不可變動的只有
裡面所儲存的指針位置保證不會發生變化,並不代表所指向的數值不會發生變動.
Next