1. 程式人生 > >IPhone開發工具篇-利用xcode profile和analyze進行效能優化

IPhone開發工具篇-利用xcode profile和analyze進行效能優化

記憶體洩漏問題的解決

記憶體洩漏(Memory Leaks)是當一個物件或變數在使用完成後沒有釋放掉,這個物件一直佔有著這塊記憶體,直到應用停止。如果這種物件過多記憶體就會耗盡,其它的應用就無法執行。這個問題在C++、C和Objective-C的MRR中是比較普遍的問題。

在Objective-C中釋放物件的記憶體是傳送release和autorelease訊息,它們都是可以將引用計數減1,當為引用計數為0時候,release訊息會使物件立刻釋放,autorelease訊息會使物件放入記憶體釋放池中延遲釋放。

上程式碼:

-(void)viewDidLoad

{[super viewDidLoad
];NSBundle*bundle =[NSBundle mainBundle];NSString*plistPath =[bundle pathForResource:@"team" ofType:@"plist"];//獲取屬性列表檔案中的全部資料self.listTeams =[[NSArray alloc] initWithContentsOfFile:plistPath];}-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {static
NSString*CellIdentifier=@”CellIdentifier”;UITableViewCell*cell =[tableView dequeueReusableCellWithIdentifier:CellIdentifier];if(cell ==nil){ cell =[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];}NSUInteger row =[indexPath row];NSDictionary*rowDict
=[self.listTeams objectAtIndex:row]; cell.textLabel.text =[rowDict objectForKey:@"name"];NSString*imagePath =[rowDict objectForKey:@"image"]; imagePath =[imagePath stringByAppendingString:@".png"]; cell.imageView.image =[UIImage imageNamed:imagePath]; cell.accessoryType =UITableViewCellAccessoryDisclosureIndicator;return cell;}-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {NSUInteger row =[indexPath row];NSDictionary*rowDict =[self.listTeams objectAtIndex:row];NSString*rowValue =[rowDict objectForKey:@"name"];NSString*message =[[NSString alloc] initWithFormat:@”您選擇了%@隊。”, rowValue];UIAlertView*alert =[[UIAlertView alloc]initWithTitle:@”請選擇球隊” message:message delegate:self cancelButtonTitle:@”Ok otherButtonTitles:nil];[alert show];[tableView deselectRowAtIndexPath:indexPath animated:YES];}

大家看看上面的3個方法會有什麼問題呢?如果程式碼是基於ARC的是沒有問題的,遺憾的是基於MRR,上面的程式碼都存在記憶體洩漏的可能性。理論上講內 存洩漏是物件或變數沒有釋放引起的,但實踐證明並非所有的未釋放物件或變數都會導致記憶體洩漏,這與硬體環境和作業系統環境有關,因此我們需要檢測工具幫助 我們找到這些“洩漏點”。

在Xcode中提供了兩種工具幫助查詢洩漏點:Analyze和Profile,Analyze是靜態分析工具可以通過選單 Product→Analyze啟動,為靜態分析之後的程式碼畫面;Profile是動態分析工具,這個工具叫“Instruments”,它是Xcode 整合在一起,可以在Xcode中通過選單Product→Profile啟動,Instruments有很多Trace Template(跟蹤模板)可以動態分析和跟蹤記憶體、CPU和檔案系統。

enter image description here

enter image description here

我們可以兩個工具結合使用查詢洩漏點,先使用Analyze靜態分析查詢可疑洩漏點,再用Profile動態分析中的Leaks和Allocations跟蹤模板進行動態跟蹤分析,確認這些點是否洩漏,或者是否有新的洩漏出現等。

其中的線段表明了程式執行的路徑,在這個路徑中,1:說明在25行Objective-C物件引用計數是1,說明在這裡建立了一個 Objective-C物件;2:說明在27行引用計數為1這個,該物件沒有釋放,懷疑有洩漏。這樣的說明已經很明顯的告訴我們問題所在了, [[NSArray alloc] initWithContentsOfFile:plistPath]建立了一個物件,並賦值給 listTeams屬性所代表的成員變數,然而完成了賦值工作之後,建立的物件並沒有顯示地傳送release和autorelease訊息。程式碼修改

NSArray*array =[[NSArray alloc] initWithContentsOfFile:plistPath];self.listTeams = array;[array release];

我們看一下tableView:cellForRowAtIndexPath:方法中的疑似洩漏點行末尾的藍色圖示展開分析結果

enter image description here

其中主要是說明UITableViewCell*型別的cell物件在64行有可能存在洩漏。在表檢視中 tableView:cellForRowAtIndexPath:方法是為表檢視單元格例項化並設定資料的,因此cell物件例項化後不能馬上 release,應該使用autorelease延遲釋放。可以在建立cell物件的時候傳送autorelease訊息,程式碼修改如下:

if(cell ==nil){

cell =[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault     reuseIdentifier:CellIdentifier] autorelease];}

我們看一下tableView:didSelectRowAtIndexPath:方法中的疑似洩漏點有兩個,行末尾的圖示展開分析結果。

enter image description here

message物件建立之後沒有釋放,我們只需要在[alert show]之後新增[message release]語句程式碼就可以了。在Objective-C中例項化物件有兩種方式:

NSString*message =[[NSString alloc] initWithFormat:@”您選擇了%@隊。”, rowValue];NSString*message =[NSString stringWithFormat:@"您選擇了%@隊。", rowValue];

①行所示以init-開頭構造方法,它的是在alloc之後呼叫該方法我們稱為“例項構造方法”,該方法建立物件所有權是呼叫者,呼叫者需要對它的 生命週期負責,具體說負責建立和釋放。而另一種是②行所示string-(去掉NS後類名)開頭方法,它是通過類直接呼叫我們稱為“類級構造方法”,該方 法是建立的物件所有權非呼叫者所有,呼叫者不無權釋放它,否則就會因過渡釋放而“殭屍化”,這個問題我們會在下一節介紹。

UIAlertView*型別alert物件建立之後沒有釋放,我們只需要在[alert show]之後新增[alert release]語句程式碼就可以了,修改之後的程式碼

-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath

{NSUInteger row =[indexPath row];NSDictionary*rowDict =[self.listTeams objectAtIndex:row];NSString*rowValue  =[rowDict objectForKey:@"name"];NSString*message =[[NSString alloc] initWithFormat:@”您選擇了%@隊。”, rowValue];UIAlertView*alert =[[UIAlertView alloc]initWithTitle:@”請選擇球隊”

message:message

delegate:self

cancelButtonTitle:@”Ok

otherButtonTitles:nil];[alert show];[alert release];[message release];[tableView deselectRowAtIndexPath:indexPath animated:YES];}

上面介紹的使用Analyze靜態分析查詢可疑洩漏點,之所以稱為“可疑洩漏點”,但是這些點未必一定洩漏,確認這些點是否洩漏還要通過 Profile動態分析工具Instruments中的Leaks和Allocations跟蹤模板,Analyze靜態分析只是一個理論上的預測過程。 通過選單Product→Profile啟動, Profile動態分析工具中選擇Leaks模板

enter image description here

Instruments中雖然是選擇了Leaks模板,但預設情況也會新增Allocations模板,基本上凡是分析記憶體都會使用 Allocations模板,它可以監控記憶體分佈情況,選中Allocations模板(圖中①區域),右邊③區域會顯示隨著時間的變化記憶體使用折線圖 表,同時在④區域會顯示記憶體使用的詳細資訊,其中剛剛物件分配情況。點選Leaks模板(圖中②區域),可以檢視記憶體洩漏情況,如果在③區域有紅線出現, 則有記憶體洩漏,④區域會顯示洩漏的物件。

enter image description here

出現的洩漏是在點選表檢視中單元格測試tableView:didSelectRowAtIndexPath:方法方法時候發生的,其中 NSCFString型別的物件發生了洩漏,NSCFString型別在NSFoundation中是NSString*型別。點選洩漏物件前面的三角形 展開物件,可以看到它們的記憶體地址、佔用位元組、所屬框架和響應方法資訊。

enter image description here

開啟擴充套件詳細檢視,可以看到右邊的跟蹤堆疊資訊,其中我們自己應用程式碼,可以點選進入我們程式程式碼,會開啟對應程式碼。enter image description here

程式碼77並不是洩漏點,而是其中的NSString*型別物件在之後發生了洩漏,因此可以斷定是message物件之後沒有釋放導致洩漏。我們修改程式碼如下:

-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath

{NSUInteger row =[indexPath row];NSDictionary*rowDict =[self.listTeams objectAtIndex:row];NSString*rowValue  =[rowDict objectForKey:@"name"];NSString*message =[[NSString alloc] initWithFormat:@”您選擇了%@隊。”, rowValue];UIAlertView*alert =[[UIAlertView alloc]initWithTitle:@”請選擇球隊”

message:message

delegate:self

cancelButtonTitle:@”Ok

otherButtonTitles:nil];[alert show];[message release];[tableView deselectRowAtIndexPath:indexPath animated:YES];}

新增[message release]語句。很多人還會猜測alert物件(UIAlertView*)會有洩漏,因此重新執行Instruments工具,反覆點選單元格測 試,並未發現表示記憶體洩漏的紅線! Instruments工具認為alert物件不釋放不會引起記憶體洩漏,如果我們想進一步評估它對於記憶體的應用,這個時候我們可以看看 Allocations模板的折線圖表,每次點選總佔用記憶體數都有所增加,這說明alert物件沒有釋放雖然不是很嚴重,但是也會增加佔用記憶體,因此 alert物件釋放也是必須的。 enter image description here

這就是我們介紹的記憶體洩漏問題解決方法,事實上記憶體洩漏是極其複雜問題,工具使用是一方面,經驗是另一方面。提高經驗,然後藉助於工具才是解決記憶體洩漏的根本。

相關推薦

IPhone開發工具-利用xcode profileanalyze進行效能優化

記憶體洩漏問題的解決 記憶體洩漏(Memory Leaks)是當一個物件或變數在使用完成後沒有釋放掉,這個物件一直佔有著這塊記憶體,直到應用停止。如果這種物件過多記憶體就會耗盡,其它的應用就無法執行。這個問題在C++、C和Objective-C的MRR中是比較普遍的問題。 在Objective-C中釋

IPhone開發工具-charles proxy的使用

軟體Charle 是一個HTTP代理伺服器,HTTP監視器,反轉代理伺服器.它允許一個開發者檢視所有連線網際網路的HTTP通訊.這些包括request, response現HTTP headers (包含cookies與caching資訊)。 官方地址:http://ww

開發工具:GitGithub

開發工具篇:Git和Github Git是什麼? Git是目前世界上最先進的分散式版本控制系統。工作原理 / 流程: Workspace:工作區 Index / Stage:暫存區 Repository:倉庫區(或本地倉庫) Remote:遠端倉庫 (一般公司內網選擇GitLab,外網可以選擇Git

奪命雷公狗C/C++-----2---開發工具

實用 img nbsp log c++ 工具 技術分享 下載 開發 微軟給大家開發了一款很給力的產品他的名字叫做visual studio 2015,當然現在有2017了,但是這個還是看您自己的愛好來實用的 下載地址我就不公布了,需要的可以私密我噢奪命雷

開發工具

itl targe 開發工具 lan 工具 bsp myeclipse eclips eclipse Eclipse MyEclipse MyEclipse_關閉可視化編輯器 開發工具篇

Java開發工具使用及其快捷鍵常見物件+JAVA學習筆記-DAY11

11.01_Java開發工具(常見開發工具介紹)(瞭解) A:作業系統自帶的記事本軟體 B:高階記事本軟體 C:整合開發環境 IDE (Integrated Development Environment) D:Eclipse和M

安裝Ubuntu後必須要做的幾件事(二)--開發工具

連結 安裝完善的編輯套件 講開發沒有編譯器,那麼一切都是浮雲。 Ubuntu預設是不安裝g++的 sudo apt-get install build-essential 下面這些看自己愛好: 安裝詞法和語法分析器 sudo

JavaScript全棧開發-工具

2017-04-13 22:17 轉載:javascript全棧開發 作者:龍付成–騰訊高階前端工程師 @IMWeb前端社群 目錄 Java早期主要作為指令碼語言執行在瀏覽器,而現在Java的使用範圍已經超越瀏覽器,向通用系統語言發展。特別是HTML5

swift開發網路利用NSURLConnection GET請求和POST請求

一、GET請求和POST請求簡單說明     @IBOutletweakvar userName:UITextField! @IBOutletweakvar userPwd:UITextField! @IBOutletweakvar logonResult:UILab

Spring ProfileMybatis進行多個數據源(H2Mysql)的切換

sql pda 開箱 https tails val 收集 sqlserver jpetstore 總結: 最近在做WebMagic的後臺,遇到一個問題:後臺用到了數據庫,本來理想情況下是用Mysql,但是為了做到開箱即用,也整合了一個嵌入式數據庫H2。這裏面就有個問題了,

[Maven]Maven中使用profilefiltering進行屬性替換

原文連結 http://www.360doc.com/content/15/0123/10/20466010_443036304.shtml 背景 構建專案時可能會遇到在測試(如單元測試)、開發、模擬、生產等不同環境下需要不同配製(properties、xml)或資源(jpg、p

使用Spring ProfileMybatis進行多個數據源(H2Mysql)的切換

轉載自:http://my.oschina.net/flashsword/blog/209872 最近在做WebMagic的後臺,遇到一個問題:後臺用到了資料庫,本來理想情況下是用Mysql,但是為了做到開箱即用,也整合了一個嵌入式資料庫H2。這裡面就有個問題了,如何用

資料型別· 第1《元組列表的效能分析、命名元組》

## 堅持原創輸出,點選藍字關注我吧 ![](https://gitee.com/qinghanstudy/qinghan/raw/master/img/20201214114911.png) 作者:清菡 部落格:oschina、雲+社群、知乎等各大平臺都有。 # 目錄 - 一、元組和列表

基於PrometheusGrafana進行效能監控_Kubernetes中文社群

1、Prometheus介紹和架構 1.1 Prometheus介紹 Prometheus是一個開源的系統監視和警報工具包,自2012成立以來,許多公司和組織採用了Prometheus。它現在是一個獨立的開源專案,並獨立於任何公司維護。在2016年,Prometheus加入雲端計算基金會作為K

Golang使用pprofqcachegrind進行效能監控-簡明教程

Golang為我們提供了非常方便的效能測試工具pprof,使用pprof可以非常方便地對Go程式的執行效率進行監測。本文講述如何使用pprof對Go程式進行效能測試,並使用qcachegrind檢視效能測試的輸出檔案。 載入pprof模組 想要對一個Go程式進行pprof監測,第一步是在main函式所在的

七、Sketchup用ruby進行二次開發--利用Transformation實現Move工具(平移、旋轉縮放)

 在Sketchup中,move工具使用的非常廣泛,,可以移動、拉伸和複製幾何體,也可以用來旋轉元件。舉一個簡單地例子。 我們要做一個建築物的尖頂,如下圖所示,就是使用move工具實現的。                   接下來我們就要學習如何使用ruby實現這樣的功能

推薦25款很棒的 HTML5 開發框架開發工具【上

  HTML5 在不同的領域讓網頁設計更強大的。快速,安全,響應式,互動和美麗,這些優點吸引更多的 Web 開發人員使用 HTML5。HTML5 有許多新的特性功能,允許開發人員和設計師建立應用程式和網站,帶給使用者桌面應用程式的速度,效能和體驗。   這篇文章整理了25款優秀的 HTML5 框架和開發工具

利用LiveReload phpstorm等開發工具自動重新整理瀏覽器

1、下載chrome外掛                2、點選livereload詳細資訊3、點選允許訪問檔案網址  4、下載livereload客戶端livereload5、將要自動重新整理的檔案目錄加到livereload6、先開啟要訪問的頁面,點選livereload

iPadiPhone開發的異同

技術 control shee sent contex 完全 屏幕方向 ges 應用 iPad特有的APIiPad多了一些特有的類,比如:UIPopoverController(左圖)UISplitViewController(右圖)… … 有

第二:php開發工具

能夠 nds 基本 數據庫 插件 運行 ins bsp asc 倍,這裏為您介紹一些常用的工具。 PHP IDE PHP IDE也不少,主要從幾個方面進行篩選: 跨平臺(能夠同時在windows,mac或者ubuntu上面運行) 版本控制(SVN,G