c語言記憶體分配
objective-c從名字來看就可以知道是一門超c語言,所以了解c語言的記憶體模型對於理解objective-c的記憶體管理有很大的幫助。c語言記憶體模型圖如下:
從圖中可以看出記憶體被分成了5個區,每個區儲存的內容如下:
1.棧區(stack):存放函式的引數值、區域性變數的值等,由編譯器自動分配釋放,通常在函式執行結束後就釋放了,其操作方式類似資料結構中的棧。棧記憶體分配運算內置於處理器的指令集,效率很高,但是分配的記憶體容量有限,比如ios中棧區的大小是2m。
2.堆區(heap):就是通過new、malloc、realloc分配的記憶體塊,它們的釋放編譯器不去管,由我們的應用程式去釋放。如果應用程式沒有釋放掉,作業系統會自動**。分配方式類似於鍊錶。
3.靜態區:全域性變數和靜態變數的儲存是放在一塊的,初始化的全域性變數和靜態變數在一塊區域,未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域。程式結束後,由系統釋放。
4.常量區:常量儲存在這裡,不允許修改的。
5.**區:存放函式體的二進位制**。
管理方式:
對於棧來講,是由編譯器自動管理,無需我們手工控制;對於堆來講,釋放工作有程式設計師控制,容易產生memory leak。
申請大小:
棧:在windows下,棧是向低位址擴充套件的資料結構,是一塊連續的記憶體區域。這句話的意思是棧頂上的位址和棧的最大容量是系統預先規定好的,在windows下,棧的大小是2m(也有的說1m,總之是編譯器確定的乙個常數),如果申請的空間超過了棧的剩餘空間時候,就overflow。因此,能獲得棧的空間較小。
堆:堆是向高位址擴充套件的資料結構,是不連續的記憶體區域。這是由於系統是用鍊錶來儲存的空閒記憶體位址的,自然是不連續的,而鍊錶的遍歷方向是由低位址向高位址。堆的大笑受限於計算機系統中有效的虛擬記憶體。由此可見,堆獲得的空間比較靈活,也比較大。
碎片的問題:
對於堆來講,頻繁的new/delete勢必會造成記憶體空間的不連續,從而造成大量的碎片,使程式效率降低。對於棧來講,則不會存在這個問題,因為棧是先進後出的佇列,他們是如此的一一對應,以至於永遠都不可能有乙個記憶體快從棧中彈出。
分配方式:
堆都是動態分配的,沒有靜態分配的堆。棧有兩種分配方式:靜態分配和動態分配。靜態分配是編譯器完成的,比如區域性變數的分配。動態分配是有alloc函式進行分配的,但是棧的動態分配和堆是不同的,他的動態分配由編譯器進行釋放,無需我們手工實現。
分配效率:
棧是機器系統提供的資料結構,計算機會在底層堆疊提供支援,分配專門的暫存器存放棧的位址,壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。堆則是c/c++函式庫提供的,他的機制是很複雜的。
棧區和堆區的區別主要為以下幾點:
對於棧來說,記憶體管理由編譯器自動分配釋放;對於堆來說,釋放工作由程式設計師控制。
棧的空間大小比堆小許多。
棧是機器系統提供的資料結構,計算機會在底層對棧提供支援,所以分配效率比堆高。
棧中儲存的變數出了作用域就無效了,而堆由於是由程式設計師進行控制釋放的,變數的生命週期可以延長。
參考文章
c 程式的記憶體管理
堆記憶體和棧記憶體的管理
1 堆記憶體 堆記憶體是由程式設計師手工管理的,但它的申請是需要借助標準庫函式。在大小上,理論上是物理記憶體的大小。關於堆記憶體的資料儲存是靠程式設計師來管理的。由於是由程式設計師管理的,程式設計師的錯誤操作也導致記憶體的洩露和記憶體碎片的問題。關於堆記憶體的標準庫函式 stdlib.h mallo...
C 的記憶體管理方式
c語言記憶體管理方式在c 中可以繼續使用,同時c 又提出了自己的記憶體管理方式 通過new和delete運算子進行動態記憶體管理。舉例來說明他們的使用 void test new和delete,new和delete一定要配合使用,不然就會導致記憶體洩漏或者崩潰的問題 new申請空間時會將括號中的物件...
C語言 聊聊記憶體的管理方式1 棧 堆和資料區
因為在校的原因,c語言學了快兩年,但偶爾沒敲 一下就忘了,特意弄個c語言的專題,記錄一下c語言中那些耐人尋味的東西。大綱來自朱有鵬老師的c語言核心深度解析,並參考一些經典的c語言書籍,順序完全是根據自己需要來排版,特此鳴謝。記憶體真的是乙個聊不完的東西,不管是構成其的器件ram,和cpu的關係,還是...