iOS性能優(yōu)化-崩潰

前言:本文旨在介紹iOS性能優(yōu)化中有關(guān)崩潰的介紹和采集。

一、APP常見的崩潰

  • 野指針,即EXC_BAD_ACCESS
  • 非法參數(shù)異常,比如參數(shù)傳為nil
  • 數(shù)組越界
  • 除0,即被除數(shù)為0
  • 方法未找到,即unrecognized selector
  • 舊設(shè)備老系統(tǒng)的崩潰
  • OOM(低內(nèi)存崩潰)
  • 崩潰到main函數(shù)

二、iOS中的崩潰類型

1、EXC_BAD_ACCESS

野指針引起的崩潰,訪問了一個已經(jīng)釋放的內(nèi)存而導(dǎo)致,向已經(jīng)釋放的對象或向它發(fā)送消息時,EXC_BAD_ACCESS就會出現(xiàn)。造成EXC_BAD_ACCESS最常見的原因是,在初始化方法中初始化變量時用錯了所有權(quán)修飾符,這會導(dǎo)致對象過早地被釋放。

2、SIGSEGV

段錯誤信息(SIGSEGV)是操作系統(tǒng)產(chǎn)生的一個更嚴(yán)重的問題。

3、SIGBUS

總線錯誤信號(SIGBUG)代表無效內(nèi)存訪問,即訪問的內(nèi)存是一個無效的內(nèi)存地址。也就是說,那個地址指向的位置根本不是物理內(nèi)存地址(它可能是某個硬件芯片的地址)。

4、SIGTRAP

SIGTRAP代表陷阱信號。它并不是一個真正的崩潰信號。它會在處理器執(zhí)行trap指令發(fā)送。LLDB調(diào)試器通常會處理此信號,并在指定的斷點處停止運行。如果你收到了原因不明的SIGTRAP,先清除上次的輸出,然后重新進(jìn)行構(gòu)建通常能解決這個問題。

5、EXC_ARITHETIC

當(dāng)要除零時,應(yīng)用會收到EXC_ARITHMETIC信號。這個錯誤應(yīng)該很容易解決。

6、SIGILL

SIGILL代表signal illegal instruction(非法指令信號)。當(dāng)在處理器上執(zhí)行非法指令時,它就會發(fā)生。執(zhí)行非法指令是指,將函數(shù)指針會給另外一個函數(shù)時,該函數(shù)指針由于某種原因是壞的,指向了一段已經(jīng)釋放的內(nèi)存或是一個數(shù)據(jù)段。

7、SIGABRT

SIGABRT代表SIGNAL ABORT(中止信號)。當(dāng)操作系統(tǒng)發(fā)現(xiàn)不安全的情況時,它能夠?qū)@種情況進(jìn)行更多的控制;必要的話,它能要求進(jìn)程進(jìn)行清理工作。

8、超時

這種崩潰通常比較容易分辨,因為錯誤碼是固定的0x8badf00d。在iOS上,它經(jīng)常出現(xiàn)在執(zhí)行一個同步網(wǎng)絡(luò)調(diào)用而阻塞主線程的情況。因此,永遠(yuǎn)不要進(jìn)行同步網(wǎng)絡(luò)調(diào)用。

9、一些被系統(tǒng)殺掉的情況,我們可以通過異常編碼來分析:

0x8badf00d,表示app在一段時間內(nèi)無響應(yīng)而被watchdog殺掉的情況
0xdeadfa11,表示app被用戶強(qiáng)制推出。
0xc00010ff,表示app因為運行造成設(shè)備溫度太高而被殺掉。

三、崩潰信息:

我們采集到的崩潰信息,主要包含的信息為:進(jìn)程信息、基本信息、異常、線程回溯。

  • 進(jìn)程信息:崩潰進(jìn)程的相關(guān)信息,比如崩潰報告唯一標(biāo)識符、唯一鍵值、設(shè)備標(biāo)識。
  • 基本信息:崩潰發(fā)生的日期、iOS版本。
  • 異常信息:異常類型、異常編碼、異常的線程。
  • 線程回溯:崩潰時的方法調(diào)用棧。

四、崩潰信息采集原理

1、捕獲異常

iOS中引發(fā)崩潰的代碼本質(zhì)上就兩類,一個是c++語言層面的錯誤,屬于比較底層的錯誤,比如野指針,除零,內(nèi)存訪問異常等等,這一類的錯誤可以通過信號機(jī)制來捕獲(signal或者是sigaction),即任何系統(tǒng)錯誤都會拋出一個錯誤信號,我們可以通過設(shè)定一個回調(diào)函數(shù),然后在回調(diào)函數(shù)里面進(jìn)行自己的處理;另一類是未捕獲異常(Uncaught Exception),iOS下面最常見的就是objective-c的NSException,比如,數(shù)組訪問元素越界。這些異常如果沒有在最上層try住,那么程序就崩潰了。

針對NSException的捕獲,通過調(diào)用NSSetUncaughtExceptionHandler來捕獲,系統(tǒng)錯誤通過注冊signal來捕獲,一般產(chǎn)生一個NSException的異常的時候,同時也會拋出一個signal的信號。

2、獲取堆棧信息

但捕獲到程序的異常后,我們需要解析app崩潰時的環(huán)境,即崩潰堆棧。

NSException的異常比較簡單,直接獲取崩潰name,reason和callstack;signal的堆棧的處理就比較麻煩些;另外,還就是需要分析APP的當(dāng)前線程信息以及所有的線程信息或者更加深一步的寄存器信息。不過這個時候拿到的堆棧是地址的形式,還需要第三步的符號表還原功能才能定位到代碼行號。

五、怎么排查崩到main函數(shù)的崩潰

  1. 設(shè)置異常崩潰-Xcode-Exception BreakPoint

  2. 設(shè)置-隱私-數(shù)據(jù)和分析-分析數(shù)據(jù),就可以導(dǎo)出崩潰日志


  3. Xcode自帶Zombie檢測的開關(guān),選擇edit scheme - Run- Diagnostics - 勾選 Zombie Objects

  4. Xcode-Window-Organizer-選擇你的APP-Crashes
    Xcode自帶的bug分析工具--Crashes Origanizer,它可以報告在app上架期間的崩潰情況。
    左側(cè)列出了App Store收集的崩潰列表,右側(cè)有詳細(xì)的崩潰原因。最有用的一個功能莫過于點擊"Open in Project"按鈕,它能直接將錯誤定位到當(dāng)前項目的崩潰點上。

六、深入了解iOS中的OOM(低內(nèi)存崩潰)

在iOS開發(fā)過程或者用戶反饋中,可能會經(jīng)??吹竭@樣的情況,用著用著就崩潰了,而在后臺查看崩潰棧的時候,找不到崩潰日志。其實這大多數(shù)的可能是系統(tǒng)產(chǎn)生了低內(nèi)存崩潰,也就是OOM(還有一種可能是主線程卡死,導(dǎo)致watchdog殺掉了應(yīng)用),而低內(nèi)存崩潰的日志,往往都是以JetsamEvent開頭的(下圖中展示),日志中有內(nèi)存頁大小(pageSize),CPU時間(cpuTime)等字段。

1、什么是OOM?

什么是OOM呢,它是out-of-memory的縮寫,字面意思就是內(nèi)存超過了限制。它是由于 iOS 的 Jetsam機(jī)制造成的一種“另類” Crash,它不同于常規(guī)的Crash,通過Signal捕獲等Crash監(jiān)控方案無法捕獲到OOM事件。

當(dāng)然還會有FOOM這樣的詞,代表的是Foreground-out-of-memory,是指App在前臺因消耗內(nèi)存過多引起系統(tǒng)強(qiáng)殺。這也就是本文要討論的。后臺出現(xiàn)OOM不一定都是app本身造成的,大多數(shù)是因為當(dāng)前在前臺的App占用內(nèi)存過大,系統(tǒng)為了保證前臺應(yīng)用正常運行,把后臺應(yīng)用清理掉了。

2、什么是Jetsam機(jī)制?

Jetsam機(jī)制可以理解為操作系統(tǒng)為了控制內(nèi)存資源過度使用而采用的一種管理機(jī)制。Jetsam是一個獨立運行的進(jìn)程,每一個進(jìn)程都有一個內(nèi)存閾值,一旦超過這個閾值Jetsam就會立刻殺掉這個進(jìn)程。

3、為什么要設(shè)計Jetsam機(jī)制?

首先設(shè)備的內(nèi)存是有限制的,并不是無限大的,所以內(nèi)存資源非常重要。系統(tǒng)進(jìn)程及用戶使用的其他app的進(jìn)程都會爭搶這個資源。由于iOS不支持交換空間,一旦觸發(fā)低內(nèi)存事件,Jetsam就會盡可能多的釋放應(yīng)用占用的內(nèi)存,這樣在iOS系統(tǒng)上出現(xiàn)系統(tǒng)內(nèi)存不足時,應(yīng)用就會被系統(tǒng)終止。

從設(shè)置-隱私-數(shù)據(jù)和分析-分析數(shù)據(jù)中導(dǎo)出的數(shù)據(jù)可以看出:以JetsamEvent開頭的則為OOM的信息


4、檢測OOM工具:

以上是有關(guān)崩潰的介紹,歡迎補(bǔ)充和指正。

參考:
iOS中的崩潰類型
深入了解iOS中的OOM(低內(nèi)存崩潰)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 描述 模擬器和真機(jī)調(diào)試運行正常,但是導(dǎo)出ipa包安裝運行出現(xiàn)奔潰。記錄一下提醒一下遇到同樣問題的人少走彎路。 思路...
    smile_frank閱讀 2,481評論 0 2
  • 一、獲取 Crash、dSYM 文件 獲取到的 .ips 改后綴為 .crash 即可 真機(jī) Crash 文件目錄...
    midmirror閱讀 9,956評論 0 31
  • 前言 嘗試寫下崩潰和主線程卡頓(ANR)的原理,以及對應(yīng)的部分解決方案和案例。 一、崩潰 業(yè)界的崩潰率標(biāo)準(zhǔn): 1、...
    羽裳有涯閱讀 2,183評論 0 1
  • 前言 iOS崩潰是讓iOS開發(fā)人員比較頭痛的事情,app崩潰了,說明代碼寫的有問題,這時如何快速定位到崩潰的地方很...
    lp_lp閱讀 5,086評論 0 16
  • 前言 iOS崩潰是讓iOS開發(fā)人員比較頭痛的事情,app崩潰了,說明代碼寫的有問題,這時如何快速定位到崩潰的地方很...
    齊滇大圣閱讀 65,917評論 29 443

友情鏈接更多精彩內(nèi)容