iOS--------對堆、棧 存儲空間的理解

Objective-C對象在內存中是以的方式分配空間的,而且堆內存是由你釋放的,即releaseios

由編譯器管理自動釋放的,在方法中(函數體)定義的變量一般是棧內所以若是你的變量要跨函數的話就須要將其定義爲成員變量。程序員

1.棧區(stack):由編譯器自動分配釋放,存放函數的參數值,局部變量等值。其操做方式相似於數據結構中的棧。objective-c

2.堆區(heap):通常由程序員分配釋放,若程序員不釋放,則可能會引發內存泄漏。注堆和數據結構中的堆棧不同,其類是與鏈表。算法

操做系統iOS 中應用程使用的計算機內存不是統一分配空間運行代碼使用的空間在三個不一樣的內存區域,分紅三個段:「text segment 「,「stack segment 」,「heap segment 」。數據結構

 

「text segment 」是應用程序運行時應用程序代碼存在的內存段每個指令,每個單個函數、過程、方法和執行代碼都存在這個內存段中直到應用程序退出。通常狀況下,你不會真的不得不知道這個段的任何事情。函數

當應用開始之後,函數main() 被調用,一些空間分配在」stack」 中。這是爲應用分配的另外一個段的內存空間,這是爲了函數變量存儲須要而分配的 內存。每一次在應用中調用一個函數,「stack 」的一部分會被分配在」stack」 中,稱之爲」frame」 。新函數的本地變量分配在這裏。spa

正如名稱所示,「stack 」是後進先出(LIFO )結構。當函數調用其餘的函數時,「stack frame 」會被建立;當其餘函數退出後,這個「frame 」會自動被破壞。操作系統

「heap」 段也稱爲」data」 段,提供一個保存中介貫穿函數的執行過程,全局和靜態變量保存在「heap」中,直到應用退出.net

爲了訪問你建立在heap 中的數據,你最少要求有一個保存在stack 中的指針,由於你的CPU 經過stack 中的指針訪問heap 中的數據。指針

你能夠認爲stack 中的一個指針僅僅是一個整型變量,保存了heap 中特定內存地址的數據。實際上,它有一點點複雜,但這是它的基本結構。

簡而言之,操做系統使用stack 段中的指針值訪問heap 段中的對象。若是stack 對象的指針沒有了,則heap 中的對象就不能訪問。這也是內存泄露的緣由。

iOS 操做系統的stack 段和heap 段中,你均可以建立數據對象。

stack 對象的優勢主要有兩點一是建立速度快,二是管理簡單,它有嚴格的生命週期

stack 對象的缺點是它不靈活建立時長度是多大就一直是多 大,建立時是哪一個函數建立的,它的owner 就一直是它。不像heap 對象那樣有多個owner ,其實多個owner 等同於引用計數。只有 heap 對象纔是採用「引用計數」方法管理它。

stack 對象的建立

只要棧的剩餘空間大於stack 對象申請建立的空間,操做系統就會爲程序提供這段內存空間,不然將報異常提示棧溢出。

heap 對象的建立

操做系統對於內存heap 段是採用鏈表進行管理的。操做系統有一個記錄空閒內存地址的鏈表,當收到程序的申請時,會遍歷鏈表,尋找第一個空間大於所申請的heap 節點,而後將該節點從空閒節點鏈表中刪除,並將該節點的空間分配給程序

例如:

NSString 的對象就是stack 中的對象,NSMutableString 的對象就是heap 中的對象。前者建立時分配的內存長度固定且不可修改;後者是分配內存長度是可變的,可有多個owner, 適用於計數管理內存管理模式

兩類對象的建立方法也不一樣,前者直接建立「NSString * str1=@"welcome"; 「,然後者須要先分配再初始化「 NSMutableString * mstr1=[[NSMutableString alloc] initWithString:@"welcome"]; 」

ios中堆棧的區別

 

管理方式:

對於棧來說,是由編譯器自動管理,無需咱們手工控制;對於堆來說,釋放工做有程序員控制,容易產生memory Leak。

申請大小:

棧:在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存區域。這句話的意思是棧頂上的地址和棧的最大容量是系統預先規定好的,在Windows下,棧的大小是2M(也有的說1M,總之是編譯器肯定的一個常數),若是申請的空間超過了棧的剩餘空間時候,就overflow。所以,能得到棧的空間較小。

堆:堆是向高地址擴展的數據結構,是不連續的內存區域。這是因爲系統是用鏈表來存儲的空閒內存地址的,天然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大笑受限於計算機系統中有效的虛擬內存。因而可知,堆得到的空間比較靈活,也比較大。

碎片的問題:

對於堆來說,頻繁的new/delete勢必會形成內存空間的不連續,從而形成大量的碎片,使程序效率下降。對於棧來說,則不會存在這個問題,由於棧是先進後出的隊列,他們是如此的一一對應,以致於永遠都不可能有一個內存快從棧中彈出。

 

分配方式

堆都是動態分配的,沒有靜態分配的堆。棧有兩種分配方式:靜態分配和動態分配。靜態分配是編譯器完成的,好比局部變量的分配。動態分配是有alloc函數進行分配的,可是棧的動態分配和堆是不一樣的,他的動態分配由編譯器進行釋放,無需咱們手工實現。

分配效率:

棧是機器系統提供的數據結構,計算機會在底層堆棧提供支持,分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。堆則是C/C++函數庫提供的,他的機制是很複雜的。

相關文章
相關標籤/搜索