先來一發蘋果官網上Instruments User Guide,其實沒啥用,英語很差的也懶得去看。(反正我是看不懂)html
關於Instruments有網友如是說的:「一句話: 內存開銷、運行速度、內存泄露 and so on」。ios
如此簡單的回答確定打發不了我們各位看官和麪試官,固然上述表達和下邊的網友總結的意思是同樣的:面試
問:您通常是怎麼使用Instruments的?算法
這個問題也就是考察下你經驗如何了, Instruments裏面工具不少,也不必逐一說明,挑幾個經常使用的說下就好:xcode
Time Profiler:分析代碼的執行時間,找出致使程序變慢的緣由。緩存
Zombies:檢查是否訪問了殭屍對象,可是這個工具只能從上往下檢查,不智能性能優化
Allocations:用來檢查內存分配,寫算法的那批人也用這個來檢查服務器
Leaks:檢查內存,看是否有內存泄露網絡
還有對Instruments這麼理解的,說的也不錯:Instruments的價值在於,它使咱們深入理解咱們代碼的內部運做。app
好了,那麼就開始咱們本身的Instruments之旅吧,揭開神祕面紗。
注:本文大部分篇幅將講述Allocations、Leaks、Time Profiler、Zombies這四項,由於是常常用到的,其餘的可能簡單介紹或者一帶而過。
關於Instruments的概述請參考Instruments概述,能夠總體的理解一下Instruments。
首先咱們要知道怎麼打開這個Instruments:在xcode中有好幾種打開的方式,具體以下:
一、
二、
三、長按啓動按鈕,選擇Profile
Instruments頁面以下,裏面全是英文,筆者爲你們用有道翻譯了一下,哪裏不對,但願你們告知,我進行修改。
其實咱們能夠看到xcode開發人員的用心,一些圖片上邊的標誌咱們一看就能明白是什麼意思,例如能量診斷,其實就是手機上邊的電池嘛🔋,還有泄漏,就是一個管子,有水滴💧滴下來了,就是泄漏的意思。還有網絡,就是一個信號塔發射信號的意思。有的看不懂不要緊,我這不是給你們翻譯了嘛。
另外有的時候Instruments的啓動按鈕是啓動不了的,這怎麼辦呢,有大神給提供了一種解決方案:Instruments啓動按鈕不可點。(在這裏謝謝標哥大神,雖然你也不看個人博客哈哈)
大概的解決方案就是:各類重啓。手機關機、重啓,同時將Xcode關掉,而後從新打開Xcode,而後從新將手機與電腦鏈接,再打開Instrument,點擊Core Animation,切換到當前的手機,發現能夠正常點擊了。
在這裏有必要說一句,這19個性能檢測的工具,有的能夠在模擬器上邊進行檢測,有的是不能夠的。若是選擇使用ios模擬器,那麼它監控的就會是你的mac,和真機仍是有區別的,譬如這個電池就應該用真機檢測,模擬器的電池沒啥可測的。而咱們的目的是手機app,固然,全部的項目都是均可以在真機上檢測的。建議你們儘可能在真機上用Istrunments。下邊咱們就逐一看看這19個性能檢測是怎麼操做的,到底怎麼就檢測了呢,檢測出來的都是什麼東西呢,會獲得什麼樣的結果呢,咱們拭目以待。
一、Blank:
空白的,沒啥可說的。
二、Activity Monitor 活動監視器:
監測CPU、內存、硬盤和網絡使用狀況,還能檢測全部的進程,檢測父/子進程的層次。默認狀況下顯示:虛擬內存大小,cup總使用量,cup用戶所使用的佔用比,cpu系統使用佔用比。推薦學習小白學習Activity Monitor。
第1部分是profile的表頭,啓動、暫停、項目名稱、運行時間等等信息均可以在上邊找到。
第2部分是左邊是性能檢測的項目名稱,右邊以豎形條形式展現運行過程當中數據值的大小,比較直觀。
第3部分是具體的性能數值,能夠選擇Details(詳細信息)和Console(控制檯),能夠看到具體的詳細信息。
三、Allocations 分配:
(!!重點之一來了!!來得如此之快,還叫人有些不適應呢)
爲何咱們要使用這個Allocations,參考Alloactions簡單使用。文章中介紹了緣由:
Allocations 的頁面以下所示:
1:堆區內存和虛擬內存佔用圖
2:堆區內存佔用圖
3:虛擬內存跟蹤圖
4:選擇使用不一樣的形式展現內存佔用狀況
5:勾選讓上面曲線圖展現對應內存佔用狀況
6:持久分配的內存所佔字節數(未釋放)即該類對象在內存中佔得總內存
7:持久建立的對象個數(未釋放)即該對象存在於內存中的個數
8:臨時分配的對象個數(未釋放)即存在過已經被回收的對象的個數
9:分配的全部內存所佔字節數(未釋放)
10:建立的對象總數(未釋放)
11:設置面板,不一樣的設置使左邊有不一樣展現效果
如上圖並不能很好的瞭解每一個方法所佔用的內存狀況,接下來咱們點擊4的call Trees以下圖設置:
接下來咱們根據內存泄漏的狀況對內存分配進行分析,內存泄漏分兩種:
第一種:爲對象A申請了內存空間,以後再也沒用到A,也沒有釋放A致使內存泄漏。這種是Leaked Memory內存泄漏。
第二種:相似於遞歸,不斷的申請內存致使的內存泄漏。根據下邊的連接文章咱們知道這種狀況就是Abandoned Memory被遺棄的內存。
說到這裏你們能夠去看看這篇文章iOS Instruments,名字雖然起的很通常,可是講了Allocations的來龍去脈。固然,下文我也拿來借鑑了。在此,謝謝文章做者luobs。
第二種狀況根據如下圖的操做能夠清晰的找到對應的問題代碼,固然不必定是咱們本身代碼的緣由,也有多是系統框架的問題。
下邊是關於尋找這個Abandoned Memory被遺棄的內存的方法:
該方法筆者沒有親測,可是看着挺可靠的,具體的步驟告訴了,按照步驟一步一步的走下來應該就能找到被遺棄的內存(看到這個「被遺棄」的詞,就想起了《記念碑谷》)
四、Automation:自動化
UI 自動測試是iOS 中重要的附加功能,它由名爲「Automation」的新的工具對象支持。Automation工具的腳本是用JavaScript語言編寫,主要用於分析應用的性能和用戶行爲,模仿/擊發被請求的事件,利用它能夠完成對被測應用的簡單的UI測試及相關功能測試。
簡單的說就是本身寫JS腳本進行測試。(最好了解JS語言最好了,不瞭解的這個Automation其實有點雞肋)
能夠參考下邊這篇文章借鑑他人UI Automation。
五、Cocoa Layout:自動佈局
Cocoa Layout能夠應用於iOS模擬器和Cocoa桌面應用,可是不能和鏈接的iOS設備一塊兒使用。Cocoa Layout提供了一個與NSLayoutConstraint類的實例有關的全部事件的時間軸,這一點和回溯(backtrace)很像。
關於這項內容網上資料並很少,你們能夠參考利用Cocoa Layout 檢視自動佈局
六、Core Animation:核心動畫
在網上查資料,大部分都是關於動畫怎麼設置的,和layer有關的動畫製做,即使前面加上Instruments,查出來的也是關於動畫製做的。。。也是醉了。幸虧咱們同事以前總結過關於這方面的,直接拿來用吧。若是你們有相關的連接,但願能給提供一下,謝謝了。
這裏咱們須要知道這個Core Animation是幹什麼的,Core Animation工具是用來檢測Core Animation性能的。(看起來這句話好像說了等於沒說,不過從這句話裏面咱們能夠看出加粗的Core Animation是咱們網上查到的利用iOS作的動畫,而前面沒有加粗的是我們Istruments裏面的Core Animation工具)
首先咱們瞭解什麼是FPS。FPS:一秒鐘渲染多少幀 Frame Per Second = FPS。
Core Animation給咱們提供了週期性的FPS,而且考慮到了發生在程序以外的動畫,界面滑動FPS能夠進行測試。通常FPS是60左右,過於低的話須要進行優化。根據下圖咱們會發現,過於低的數值是低於45。
看上圖,咱們主要介紹右邊「設置」裏面的相關內容。
Color Blended Layers混合過分繪製
這個選項基於渲染程度對屏幕中的混合區域進行綠到紅的高亮(也就是多個半透明圖層的疊加)。因爲重繪的緣由,混合對GPU性能會有影響,同時也是滑動或者動畫幀率降低的罪魁禍首之一。
這樣就能在模擬器上邊看到這個Color Blended Layers
GPU每一幀能夠繪製的像素有一個最大限制(就是所謂的fill rate),這個狀況下能夠輕易地繪製整個屏幕的全部像素。可是若是因爲重疊圖層的關係須要不停地重繪同一區域的話,掉幀就可能發生了。
GPU會放棄繪製那些徹底被其餘圖層遮擋的像素,可是要計算出一個圖層是否被遮擋也是至關複雜而且會消耗處理器資源。一樣,合併不一樣圖層的透明重疊像素(即混合)消耗的資源也是至關客觀的。因此爲了加速處理進程,不到必須時刻不要使用透明圖層。任何狀況下,你應該這樣作:
給視圖的backgroundColor屬性設置一個固定的,不透明的顏色
設置opaque屬性爲YES
注意:下邊的內容爲咱們解釋了爲何在tableview性能優化中咱們提到的平衡CPU和GPU裏面關於Core Animation的緣由。
(關於CPU和GPU能夠參考CPU與GPU)
若是用到了圖像,儘可能避免透明除非很是必要。若是圖像要顯示在一個固定的背景顏色或是固定的背景圖以前,你不必相對前景移動,你只須要預填充背景圖片就能夠避免運行時混色了。
若是是文本的話,一個白色背景的UILabel(或者其餘顏色)會比透明背景要更高效。
Color Offscreen-Rendered Yellow(離屏渲染)
這裏會把那些須要離屏渲染的圖層高亮成黃色。這些圖層極可能須要用shadowPath或者shouldRasterize來優化。
當圖層屬性的混合體被指定爲在未預合成以前不能直接在屏幕中繪製時,屏幕外渲染就被喚起了。屏幕外渲染並不意味着軟件繪製,可是它意味着圖層必須在被顯示以前在一個屏幕外上下文中被渲染(不論CPU仍是GPU)。圖層的如下屬性將會觸發屏幕外繪製:
一、圓角(當和maskToBounds一塊兒使用時)
二、圖層蒙板
三、陰影
屏幕外渲染和咱們啓用光柵化時類似,除了它並無像光柵化圖層那麼消耗大,子圖層並無被影響到,並且結果也沒有被緩存,因此不會有長期的內存佔用。可是,若是太多圖層在屏幕外渲染依然會影響到性能。
有時候咱們能夠把那些須要屏幕外繪製的圖層開啓光柵化以做爲一個優化方式,前提是這些圖層並不會被頻繁地重繪。
對於那些須要動畫並且要在屏幕外渲染的圖層來講,你能夠用CAShapeLayer,contentsCenter或者shadowPath來得到一樣的表現並且較少地影響到性能。
Color Hits Greenand Misses Red(光柵化緩存圖層命中狀況)
當使用shouldRasterizep屬性的時候,耗時的圖層繪製會被緩存,而後當作一個簡單的扁平圖片呈現。當緩存再生的時候這個選項就用紅色對柵格化圖層進行了高亮。若是緩存頻繁再生的話,就意味着柵格化可能會有負面的性能影響了。
Color Copied Images 拷貝的圖片
有時候寄宿圖片的生成意味着Core Animation被強制生成一些圖片,而後發送到渲染服務器,而不是簡單的指向原始指針。這個選項把這些圖片渲染成藍色。複製圖片對內存和CPU使用來講都是一項很是昂貴的操做,因此應該儘量的避免。
Color Immediately 顏色當即更新
一般Core Animation Instruments以每毫秒10次的頻率更新圖層調試顏色。對某些效果來講,這顯然太慢了。這個選項就能夠用來設置每幀都更新(可能會影響到渲染性能,並且會致使幀率測量不許,因此不要一直都設置它)。
Color Misaligned Images(圖片的不正常縮放)
-這裏會高亮那些被縮放或者拉伸以及沒有正確對齊到像素邊界的圖片(也就是非整型座標)。這些中的大多數一般都會致使圖片的不正常縮放,若是把一張大圖當縮略圖顯示,或者不正確地模糊圖像,那麼這個選項將會幫你識別出問題所在。
Color OpenGL Fast Path Blue
這個選項會對任何直接使用OpenGL繪製的圖層進行高亮。若是僅僅使用UIKit或者Core Animation的API,那麼不會有任何效果。若是使用GLKView或者CAEAGLLayer,那若是不顯示藍色塊的話就意味着你正在強制CPU渲染額外的紋理,而不是繪製到屏幕。
Flash Updated Regions(Core Graphics繪製的圖層)
-這個選項會對重繪的內容高亮成黃色(也就是任何在軟件層面使用Core Graphics繪製的圖層)。這種繪圖的速度很慢。若是頻繁發生這種狀況的話,這意味着有一個隱藏的bug或者說經過增長緩存或者使用替代方案會有提高性能的空間。
七、Core Data 核心數據
依舊是咱們在網上查找資料,好多資料都是關於如何使用CoreData存儲數據的,即使咱們在前面加上Istruments,查到的資料仍是關於如何存儲數據的,還好咱們另外一位同事找到了資料。
Core data也叫檢測核心數據故障的儀器,主要是用於監測讀取、緩存未命中、保存等操做,能直觀顯示是否保存次數遠超實際須要。如下的instruments工具收集的數據和Core Data應用的事件相關。你可使用這些instruments工具返回的信息來評估各類事件對應用性能的影響和來定位潛在問題並修復它。
Core data instrument工具能夠運行在單一進程或全部系統當前運行的進程之上。它只會記錄使用Core Data的進程的數據。該instrument工具在實現上使用了DTrace,並能夠導入DTrace腳本。
Core Data Fetches 工具記錄Core Data應用中提取保存數據的操做。
Core Data Cache Misses 工具記錄高速緩存未命中致使的故障事件。
Core Data Saves 工具記錄了Core Data應用中保存的操做。
八、Counters 計數器
從用戶管理的點事件計數器儀器記錄信息。它能夠記錄從一個過程或系統上運行的全部進程的信息。
九、Energy Diagnostic 能量診斷
用於Xcode下的Instruments來分析手機電量消耗的。(必須是真機纔有電量)
十、File Activity 文件活動
按照介紹this template monitors file and directory activity ,including file open close calls,file permission modifications, directory creation ,file moves ,etc.翻譯過來是:這個模板活動監視器文件和目錄,包括文件打開或者關閉,文件權限修改,目錄建立,文件移動等。
十一、GPU Driver 顯卡驅動程序
GPU Driver能夠測量GPU的利用率,一樣也是一個很好的來判斷和GPU相關動畫性能的指示器。它一樣也提供了相似Core Animtaion那樣顯示FPS的工具。
看來這個GPU Driver 仍是和Core Animation有關。
十二、Leaks 泄漏
(!!又一個重頭戲來了!!)
首先咱們看一看內存溢出和內存泄漏的區別。
內存溢出 out of memory,是指程序在申請內存時,沒有足夠的內存空間供其使用,出現out of memory;好比申請了一個integer,但給它存了long才能存下的數,那就是內存溢出。
內存泄露 memory leak,是指程序在申請內存後,沒法釋放已申請的內存空間,一次內存泄露危害能夠忽略,但內存泄露堆積後果很嚴重,不管多少內存,早晚會被佔光。
memory leak會最終會致使out of memory!
在前面的ALLcations裏面咱們提到過內存泄漏就是應該釋放而沒有釋放的內存。而內存泄漏分爲兩種:Leaked Memory 和Abandoned Memory。前面咱們講到了如何找到Abandoned Memory被遺忘的內存,如今咱們研究的就是Leaked Memory。
以發生的方式來分類,內存泄漏能夠分爲4類:
常發性內存泄漏。發生內存泄漏的代碼會被屢次執行到,每次被執行的時候都會致使一塊內存泄漏。
偶發性內存泄漏。發生內存泄漏的代碼只有在某些特定環境或操做過程下才會發生。常發性和偶發性是相對的。對於特定的環境,偶發性的也許就變成了常發性的。因此測試環境和測試方法對檢測內存泄漏相當重要。
一次性內存泄漏。發生內存泄漏的代碼只會被執行一次,或者因爲算法上的缺陷,致使總會有一塊僅且一塊內存發生泄漏。好比,在類的構造函數中分配內存,在析構函數中卻沒有釋放該內存,因此內存泄漏只會發生一次。
隱式內存泄漏。程序在運行過程當中不停的分配內存,可是直到結束的時候才釋放內存。嚴格的說這裏並無發生內存泄漏,由於最終程序釋放了全部申請的內存。可是對於一個服務器程序,須要運行幾天,幾周甚至幾個月,不及時釋放內存也可能致使最終耗盡系統的全部內存。因此,咱們稱這類內存泄漏爲隱式內存泄漏。
影響:從用戶使用程序的角度來看,內存泄漏自己不會產生什麼危害,做爲通常的用戶,根本感受不到內存泄漏的存在。真正有危害的是內存泄漏的堆積,這會最終消耗盡系統全部的內存。從這個角度來講,一次性內存泄漏並無什麼危害,由於它不會堆積,而隱式內存泄漏危害性則很是大,由於較之於常發性和偶發性內存泄漏它更難被檢測到。
下邊咱們介紹Instruments裏面的Leaked的用法,首先打開Leaked,跑起工程來,點擊要測試的頁面,若是有內存泄漏,會出現下圖中的紅色的❌。而後按照後邊的步驟進行修復便可。
下圖是對Leaked頁面進一步的理解:
固然了,關於內存泄漏咱們還能夠用 command +shift +B 的方式進行檢測,這個快捷鍵調起的是內存管理器Analyze。
也能夠從Product裏面直接打開
關於內存管理器Analyze解決問題能夠參考這篇文章APP Analyze(靜態分析)也能夠參考Analyze問題解決。
使用內存管理器遇到的問題大概分爲:
一、garbage value(垃圾值)
二、never read(分配了空閒內存)
三、Null passed to a callee that requires a non-null 1st parameter(Null賦值給非空對象)
四、Potential leak of an object stored into 'XX'(存在潛在的內存泄露)
上述兩篇文章很好的解答了出線這4個問題如何解決,這裏就不贅述了。
關於內存泄露仍是比較重要的,你們看看,測試一下本身項目裏面的內存泄漏,另外若是你們有什麼更好的方法,但願可以告訴我,謝謝。
使用上述兩種方法(1)Instruments-Leaked (2)內存管理器Analyze 來檢查內存泄漏,是咱們最經常使用的兩種。
1三、Metal System Trace
金屬系統跟蹤
翻譯下圖紅框的英文獲得:金屬ios系統跟蹤配置文件的性能應用程序從應用程序經過提供跟蹤信息,司機和GPU層。(狗屁不通)從網上找Metal System Trace相關的資料也沒有找到。誰知道這是幹啥用的。
1四、Network 網絡
一樣是翻譯下邊的英文:分析應用程序如何使用TCP / IP和UDP / IP鏈接使用鏈接儀器。就是檢查手機網速的。(這個最好是真機)
1五、OpenGL ES Analysis openGL分析
一樣是翻譯下邊的英文:這個模板的措施和分析OpenGL ES活動檢測OpenGL ES正確性和性能問題也提供瞭解決這些問題的建議。
1六、System Trace 系統跟蹤
該模板提供了系統行爲的全面信息。它顯示線程什麼時候調度,並顯示從用戶到系統代碼的線程轉換,經過系統調用和內存操做。這個模板能夠在OS X操做系統和iOS上使用。包含三個模板
Scheduling Instrument------調度工具
System Calls Instrument---系統調用儀器
VM Tracker Instrument-----VM跟蹤儀
1七、System Usage 系統使用
這個模板監視一個應用程序和記錄系統的I / O活動相關的文件,套接字和共享內存。這包括輸入,輸出,時間回溯,調用樹,乃至每一次響應。該模板只可用於iOS。包含一個模板
I/O Activity Instrument-----I/O活動儀
I/O Activity instrument工具記錄I/O事件:函數調用,好比在文件系統上面的read、write、open、close等操做。你可使用該instrument工具來啓動和樣本分析單個運行在iOS設備上面的進程。儘管I/O Activity instrument工具提供了一個調用樹的回溯跟蹤視圖,在Mac OS X上有相似I/O Activity instrument工具的fs_usage實用工具。
1八、Time Profiler 時間分析器
(又一個重頭戲!!!)
用來檢測app中每一個方法所用的時間,而且能夠排序,並查找出哪些函數佔用了大量時間。頁面以下:
使用Time Profile前有兩點須要注意的地方:
一、必定要使用真機調試
在開始進行應用程序性能分析的時候,必定要使用真機。由於模擬器運行在Mac上,然而Mac上的CPU每每比iOS設備要快。相反,Mac上的GPU和iOS設備的徹底不同,模擬器不得已要在軟件層面(CPU)模擬設備的GPU,這意味着GPU相關的操做在模擬器上運行的更慢,尤爲是使用CAEAGLLayer來寫一些OpenGL的代碼時候,這就致使模擬器性能數據和用戶真機使用性能數據相去甚遠
二、應用程序必定要使用發佈配置
在發佈環境打包的時候,編譯器會引入一系列提升性能的優化,例如去掉調試符號或者移除並從新組織代碼。另iOS引入一種"Watch Dog"[看門狗]機制,不一樣的場景下,「看門狗」會監測應用的性能,若是超出了該場景所規定的運行時間,「看門狗」就會強制終結這個應用的進程。開發者能夠crashlog看到對應的日誌,但Xcode在調試配置下會禁用"Watch Dog"
下面解釋了每個選項對左側列表中數據的顯示起了什麼做用:
Separate by Thread:每一個線程被單獨考慮。這能讓你知道哪個線程佔用CPU最多。
Invert Call Tree:選中該選項後,調用棧會自上至下顯示。這一般是你須要的,由於你想知道CPU花費時間的那個最深的方法。
Hide System Libraries:選中該選項後,只有你本身app中出現的符號會被顯示出來。一般選中該選項是有用的,由於你只關心CPU在你本身的代碼中的哪一部分花費時間,你無法對系統庫使用CPU作多少改變。
Flatten Recursion:該選項將每個調用棧中的遞歸函數(調用它們自身的函數)視做單一入口,而不是多入口。
Top Functions:選上這一選項讓Instruments將花費在一個函數中的總時間視做在該函數中直接花費的時間加上調用的其餘函數花費的時間。因此若是函數A調用了函數B,那麼函數A花費的總時間被記爲A花費的時間加上B花費的時間。這一選項很是有用,由於它能讓你在每次進入調用棧時找到花費最長的時間,瞄準你最耗時的方法。
看到網上有人說主線程耗時過多進行優化的,有的是網絡請求耗時過多進行優化的,有的是UIImage耗時過多進行優化的,總之,能夠看到哪一個函數耗時多,進而優化,在這裏不禁得想起了本文開頭提到的一位網友說的:Instruments的價值在於,它使咱們深入理解咱們代碼的內部運做。誠不欺吾。
總結:性能優化是在全部更能實現完成時要作的事,使用Time Profile工具分析app每一個流程的執行狀況,發現耗時的地方,合理優化,提高用戶體驗,切記,優化後要作一遍詳細的測試,別修了東牆壞了西牆。
1九、Zombies 殭屍
(最後一個,也是最後一個重頭戲)
翻譯英文:專一於檢測過分釋放的「殭屍」對象。還提供了數據對象分配的類以及全部活動分配內存地址的歷史。
這裏咱們能夠看到一個詞語叫「over-release」,過分釋放。咱們在項目中見到最多的就是「EXC_BAD_ACCESS」或者是這樣的:Thread 1: Program received signal:"EXC_BAD_ACCESS",這就是訪問了被釋放的內存地址形成的。過分釋放,是對同一個對象釋放了過多的次數,其實當引用計數降到0時,對象佔用的內存已經被釋放掉,此時指向原對象的指針就成了「懸垂指針」,如若再對其進行任何方法的調用,(原則上)都會直接crash(然而因爲某些特殊的狀況,不會立刻crash)。過分釋放簡單的說就是對release的對象再release,就是過分釋放。
咱們須要知道這幾個概念:
一、內存泄漏:對象使用完沒有釋放,致使內存浪費。
二、殭屍對象:已經被銷燬的對象(不能再使用的對象)
三、野指針:指向殭屍對象(不可用內存)的指針。給野指針發消息會報EXC_BAD_ACCECC錯誤。
四、空指針:沒有指向儲存空間的指針(裏面存的是nil,也就是0)。在oc中使用空指針調中方法不會報錯。
注意:爲了不野指針錯誤的常見方法:在對象被銷燬以後,將指向對象的指針變爲空指針。
對於過分釋放的問題,能夠直接使用Zombie,當過分釋放發生時會當即停在發生問題的位置,同時結合內存分配釋放歷史和調用棧,能夠發現問題。至於上文提到的不會crash的緣由,其實有不少,好比:
對象內存釋放時,所用內存並無徹底被擦除,仍有舊對象部分數據可用
原內存位置被寫入同類或一樣結構的數據
咱們將殭屍對象「復活」的目的:殭屍對象就是讓已經釋放了的對象從新復活,便於調試;是爲了讓已經釋放了的對象在被再次訪問時可以輸出一些錯誤信息。其實這裏的「復活」並非真的復活,而是強行不死:這麼說吧 至關於 他的RC=0的時候 系統再強行讓他RC=1,順便打上一個標記 zoom,等到你去掉那個溝之後 系統會把帶有標記zoom的對象RC=0。
能夠參考IOS性能調優系列:使用Zombies動態分析內存中的殭屍對象
能夠參考ios 調試技巧收藏 一 解決EXC_BAD_ACCESS錯誤的一種方法--NSZombieEnabled
能夠參考野指針與殭屍對象
下邊是Instruments裏面的Zombies的用法:
接下來進行設置,在Launch Configuration中勾選Record reference counts和Enable NSZombie detection。其中Recordreference counts是顯示引用計數,Enable NSZombie detection是可以檢測殭屍對象。
這樣在程序運行的時候,若是發現殭屍對象它就會彈出一個對話框,點擊其中「→」按鈕,在屏幕的下方會顯示殭屍對象的詳細信息,下圖能夠看到殭屍對象的引用計數變化狀況。
注意:Zombies模版在使用的時候會致使內存的飆升,這是由於全部被釋放的對象被殭屍對象取代,並未真的釋放掉,在結束Zombies時會釋放,這是預知行爲,這就意味着instrument裏的其它工具和Zombies是不能同時使用的,Zombies會致使其它的數據不許。包括leaks,你也不該該把它加到Zombies模版中,即便這麼作告終果也沒什麼意義。對於iOS應用來講,在用Zombies模版時使用iOS模擬器比真機要好。
另外XCode也提供了手動設置NSZombieEnabled環境變量的方法,不過設置NSZombieEnabled爲True後,會致使內存佔用的增加,同時會影響Leaks工具的調試,這是由於設置NSZombieEnabled會用殭屍對象來代替已釋放對象。
點擊Product菜單Edit Scheme打開該頁面,而後勾選Enable Zombie Objects複選框:
最後提醒的是NSZombieEnabled只能在調試的時候使用,千萬不要忘記在產品發佈的時候去掉,由於NSZombieEnabled不會真正去釋放dealloc對象的內存,一直開啓的話,該死去的對象會一直存在,後果可想而知,自重!
好了,結束了。仍是那句話:Instruments的價值在於,它使咱們深入理解咱們代碼的內部運做。
最後,哪裏不對的地方能夠給我留言,我會及時改進的,謝謝你們。
做者:和珏貓 連接:http://www.jianshu.com/p/9e94e42cfb01 來源:簡書 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。