這一階段我們主要來講講iOS記憶體管理方面的知識,面試的時候可能大家多多少少都會被問及這方面的問題,那我們就從常見的面試題開講
- 使用
、CADisplayLink
有什麼注意點?NSTimer
- 介紹下記憶體的幾大區域
- 講一下你對iOS記憶體管理的了解
-
都幫我們做了什麼?ARC
-
的實作原理weak指針
-
對象在什麼時機會被調用autorelease
release
- 方法裡有局部對象,出了方法後會
嗎?立即釋放
上一篇我們說了
定時器
和
CADisplayLink
,今天我們來說說第二條,介紹下
iOS的記憶體布局
##我們從低向高看依次是
- 記憶體的低位址是保留的
- 代碼段(__TEXT)
編譯之後的代碼
- 資料段(__DATA)
字元串常量:比如NSString *str = @“123”
已初始化資料:已初始化的全局變量、靜态變量等
未初始化資料:未初始化的全局變量、靜态變量等
- 堆(heap)
通過、
alloc
、
malloc
等動态配置設定的空間,配置設定的記憶體空間位址
calloc
越來越大
- 棧(stack)
函數調用開銷,比如。配置設定的記憶體空間位址
局部變量
越來越小
- 核心區
保留區和核心區我們是用不到的
##下面我們來寫代碼驗證下
我們建立一個工程,我們就直接在main檔案裡直接寫了
int a = 10;
int b;
int main(int argc, char * argv[]) {
@autoreleasepool {
static int c = 20;
static int d;
int e;
int f = 20;
NSString *str = @"123";
NSObject *obj = [[NSObject alloc] init];
NSLog(@"\n&a=%p\n&b=%p\n&c=%p\n&d=%p\n&e=%p\n&f=%p\nstr=%p\nobj=%p\n",
&a, &b, &c, &d, &e, &f, str, obj);
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
然後我們運作下看終端日志輸出
/*
字元串常量
str=0x10dfa0068
已初始化的全局變量、靜态變量
&a =0x10dfa0db8
&c =0x10dfa0dbc
未初始化的全局變量、靜态變量
&d =0x10dfa0e80
&b =0x10dfa0e84
堆
obj=0x608000012210
棧
&f =0x7ffee1c60fe0
&e =0x7ffee1c60fe4
*/
我們可以看到跟我們畫的圖是一樣的
- 字元串常量的記憶體位址 < 已初始化的全局變量、靜态變量 < 未初始化的全局變量、靜态變量 < 堆 < 棧
- 我們還發現
和全局變量
的記憶體位址是靜态變量
,是以我們可以說挨着的
(不管放在那裡方法内部也好外部也好)和靜态變量
是一樣的記憶體是全局變量
的,編譯完以後它們就已經确定了放在了一塊的隻有一份
- 還有就是我們看到
到資料段
和堆
的位址跨度非常大,是以系統留給我們的棧
和堆
的空間是棧
的非常大
- 還有一點就是由于
配置設定的空間位址堆
,而越來越大
配置設定的空間位址棧
,也就是說越來越小
和堆
之間的位址有可能是棧
,也可能是堆空間
棧空間
One More Thing
喜歡的朋友可以掃描關注我的公衆号(多多點贊,多多打賞,您的支援是我寫作的最大動力)