你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS:堆(heap)和棧(stack)的理解

iOS:堆(heap)和棧(stack)的理解

編輯:IOS開發綜合

Object-c的對象在內存中是以堆的方式分配內存空間的,並且堆內存是由你釋放的,即release

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

2.堆區(heap):一般由程序員分配釋放,若程序員不釋放,則可能會引起內存洩漏。注堆和數據結構中的堆棧不一樣,其類是與鏈表。

操作系統iOS 中應用程序使用的計算機內存不是統一分配空間,運行代碼使用的空間在三個不同的內存區域,分成三個段:“text segment “,“stack segment ”,“heap segment ”。

\

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

當應用開始以後,函數main() 被調用,一些空間分配在”stack” 中。這是為應用分配的另一個段的內存空間,這是為了函數變量存儲需要而分配的 內存。每一次在應用中調用一個函數,“stack ”的一部分會被分配在”stack” 中,稱之為”frame” 。新函數的本地變量分配在這裡。

正如名稱所示,“stack ”是後進先出(LIFO )結構。當函數調用其他的函數時,“stack frame ”會被創建;當其他函數退出後,這個“frame ”會自動被破壞。

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

為了訪問你創建在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"]; ”。


  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved