整理下最近看的文章,主要取自這里
棧區(qū)
由編譯器自動分配釋放,存放函數(shù)的參數(shù)值,局部變量等值。
棧是一個用來存儲局部和臨時變量的存儲空間。
在現(xiàn)代操作系統(tǒng)中,一個線程會分配一個棧. 當一個函數(shù)被調用,一個stack frame(棧幀)就會被壓到stack里。里面包含這個函數(shù)涉及的參數(shù),局部變量,返回地址等相關信息。當函數(shù)返回后,這個棧幀就會被銷毀。而這一切都是自動的,由系統(tǒng)幫我們進行分配與銷毀。對于程序員來說,我們無須自己調度。
棧是向低地址擴展的數(shù)據(jù)結構,是一塊連續(xù)的內存的區(qū)域。是棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預先規(guī)定好的,棧的大小是2M(也有的說是1M,總之是一個編譯時就確定的常數(shù) ) ,如果申請的空間超過棧的剩余空間時,將提示overflow。因此,能從棧獲得的空間較小。
堆區(qū)
一般由程序員分配釋放,若程序員不釋放,則可能會引起內存泄漏。
堆從本質上來說,程序中所有的一切都在內存中(有些東西是不在堆棧中的,但在這篇文章中我們不作討論)。在堆上,我們可以任何時候分配內存空間以及釋放銷毀它。你必須顯示的請求在堆上分配內存空間,如果你不使用垃圾回收機制,你必須顯示的去釋放它。這就是在你的函數(shù)調用前需要完成的事情。簡單來說,就是malloc與free。
通常以這種方式創(chuàng)建對象:
NSObject *obj = [[NSObject alloc] init];
系統(tǒng)會在棧上存儲obj這個指針變量,它所指的對象在堆中。通過[NSObject alloc]系統(tǒng)會為其在堆中開辟一塊內存空間,并為其生成NSObject所需內存結構布局。
堆是向高地址擴展的數(shù)據(jù)結構,是不連續(xù)的內存區(qū)域。這是由于系統(tǒng)是用鏈表來存儲的空閑內存地址的,自然是不連續(xù)的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限于計算機系統(tǒng)中有效的虛擬內存。由此可見,堆獲得的空間比較靈活,也比較大。
棧對象:
? ?? 優(yōu)點:1.高速,在棧上分配內存是非??斓?。
? ? ? ? ? ? ? ? 2.簡單,棧對象有自己的生命周期,你永遠不可能發(fā)生內存泄露。因為他總是在超出他的作用域時被自動銷毀了
? ? ?缺點:棧對象嚴格的定義了生命周期也是其主要的缺點,棧對象的生命周期不適于Objective-C的引用計數(shù)內存管理方法。
在objective-c中只支持一個類型對象:blocks。
關于在block中的對象的生命周期問題。出現(xiàn)這問題的原因是,block是新的對象,當你使用block時候,如果你想對其保持引用,你需要對其進行copy操作,(從棧上copy到堆中,并返回一個指向他的指針),而不是對其進行retain操作
堆對象:
? ? 優(yōu)點:可以自己控制對象的生命周期。
? ? 缺點:需要程序員手動釋放,容易造成內存泄漏。
全局區(qū)(靜態(tài)區(qū))
全局變量和靜態(tài)變量的存儲是放在一起的,初始化的全局變量和靜態(tài)變量存放在一塊區(qū)域,未初始化的全局變量和靜態(tài)變量在相鄰的另一塊區(qū)域,程序結束后有系統(tǒng)釋放。
注意:全局區(qū)又可分為:
未初始化全局區(qū):.bss段
初始化全局區(qū):data段。
舉例:int a;未初始化的。int a = 10;已初始化的。
例子代碼:
int a = 10;? 全局初始化區(qū)
char *p;? 全局未初始化區(qū)
main{
int b; 棧區(qū)
char s[] ="abc"棧
char *p1; 棧
char *p2 ="123456";123456\\\\0在常量區(qū),p2在棧上。
static int c =0; 全局(靜態(tài))初始化區(qū)
w1 = (char *)malloc(10);
w2 = (char *)malloc(20);
分配得來得10和20字節(jié)的區(qū)域就在堆區(qū)。
}
常量區(qū)
存放常量字符串,程序結束后由系統(tǒng)釋放
代碼區(qū)
存放函數(shù)的二進制代碼
