你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> WWDC - iOS內存性能及原理 筆記

WWDC - iOS內存性能及原理 筆記

編輯:IOS開發綜合

iOS內存的基本原理

內存是如何初始化和被管理的?

在iOS內,指針的地址范圍很大, 32位CPU上有 4GB 大小, 64位CPU上有 18EB 大小 (大約有2的60次方), 這麼大的指針地址范圍會致使我們看來系統內存有這麼大,實際上物理內存可能沒有這麼大,這個大小被稱為虛擬內存, 在OS X 中系統使用硬盤來存儲內存中不經常使用的數據來作為內存的後備存儲, 在內存中存有硬盤數據的指針地址, 需要的事後才寫入內存.

然而, 在iOS中沒有後備存儲, iOS中只讀類型的數據已經存在硬盤上, 在需要時寫入內存使用, 可讀寫數據是常駐內存的,不會移除, 一旦可使用內存達到臨界值, 系統會發出內存不夠用的警告,由應用程序主動釋放資源,若釋放失敗或沒有排除警告,會直接被系統終結程序.

虛擬內存
iOS的物理內存被分割成大小為 4KB 的頁, 而且不是所有的頁都能被應用訪問到. 虛擬內存是在kernel和應用層之間的一層,由於當我們每次需要內存的時候都直接調用kernel去申請內存的過程的代價是很大的, 所以底層會直接與虛擬內存申請空間, 虛擬內存會與kernel通信, 創建 VM Object來匹配物理內存,如圖:
title=
在內存的堆中, 我們應用的數據只占一部分, 其他還有framework創建的對象和緩存, 內存中還有一些靜態常量, 線程的堆棧, 圖片數據, CALayer的緩存, 數據庫的緩存

內存類型: 干淨內存和髒內存

干淨內存: 從磁盤上拷貝到內存中的空間, 比如, 代碼, framework,內存映射文件.
髒內存: 其他的內存空間. 比如 在堆上的初始化數據, 數據庫緩存,解壓的圖片數據等.
大部分應用初始化的數據都是髒內存
舉例如下:

- (void)displayWelcomeMessage {
NSString *welcomeMessage = [NSString stringWithUTF8String:“Welcome to WWDC!”];
self.alertView.title = welcomeMessage;
[self.alertView show];
}

welcomeMessage 是髒內存, 因為字符串Welcome to WWDC! 在靜態數據區,它倍復制一份到堆上給了welcomeMessage.

- (void)displayWelcomeMessage {
NSString *welcomeMessage = @”Welcome to WWDC!”;
self.alertView.title = welcomeMessage;
[self.alertView show];
}

這次welcomeMessage是干淨內存, 因為沒有復制一份.

- (void)allocateSomeMemory {
void *buf = malloc(10 * 1024 * 1024);
…
}

雖然malloc是在堆上初始化數據, 但是 buf 沒有實際存儲數據, 所有buf是干淨內存.

- (void)allocateSomeMemory {
void *buf = malloc(10 * 1024 * 1024);
for (unsigned int i = 0; i < sizeof(buf), i++) {
 buf[i] = (char)random();
}
…
}

但是一旦使用了buf後, buf就是髒內存了.

UIImage *wwdcLogo = [UIImage imageNamed:@”WWDC12Logo”];

初始化UIImage,UIImage其實是CGImage的包裝, CGImage生成jpeg 和 bitmap, 在內存中會有未壓縮的bitmap數據,是髒內存.

當iOS運行在低內存是會發生什麼

iOS開始的時候, 干淨內存比例很大,當我們運行app的時候, 隨著運行的進行, 初始化數據, 產生了髒內存, 進而是髒內存比例增大,干淨內存比例減小, 最後產生內存壓力, 內存不夠用了, 這時候系統會終結掉後台應用, 釋放屬於應用的髒數據, 騰出內存空間.

內存警告

這是一次挑戰

會發生在內存有限的設備上 是最後保護用戶體驗的機會 保證你的應用能響應內存警告,警告通知是在主線程上觸發,避免重復的初始化大數據

這是一次機會

盡可能的釋放內存,但是不要影響用戶體驗 內存警告傳遞到應用程序有幾種方式:
通知
UIApplicationDidReceiveMemoryWarningNotification UIApplication代理方法 -[id -applicationDidReceiveMemoryWarning:] UIViewController方法
-[UIViewController didReceiveMemoryWarning]

一定要注意髒內存,因為髒內存是由應用創建,如果不清除,只有應用被終結後才能釋放, 使用Profile的VM Tracker去檢測內存使用情況, 避免出現大范圍經常性波動, 減少內存還可以使用 @autoreleasepool.

找到內存的問題

減少內存的使用: 清楚我們應用的視圖層級,只創建必要的視圖. 避免循環的導致堆增長,不要忽略那些小的對象. 避免內存增長:
不可訪問的,沒有任何指針指向 不能被再次使用 被拋棄的內存
仍然有指針引用它, 但是被浪費的 從未被使用過 緩存
被引用了和等待使用 可能永遠不會被使用了

如何檢測內存問題
內存不應該在重復一個操作中持續增長, 比如: push和pop UIViewcontroller,滑動UITableview, 操作數據庫搜索

使用工具和陷阱

使用 Allocations Instrument 來檢測內存是否洩露, 遇到內存洩露可以檢查是否在塊中使用了self對象, 應該換成 __weak 修飾的self這樣不增加計數引用.
更多的信息可以查閱官方手冊.
Instruments Documentation
Instruments User Guide
Instruments User Reference
地址

官方關於虛擬內存的說明

 

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