iOS內(nèi)存分析之Memory Graph

1.Memory Graph是什么

Memory Graph是在Xcode8上推出的一個(gè)新特性句柠。用來(lái)生成應(yīng)用程序中對(duì)象分配的內(nèi)存圖浦译。

2.Memory Graph用來(lái)做什么

  • Memory Graph可以幫助我們找到循環(huán)引用和內(nèi)存泄漏棒假,正在使用的內(nèi)存以及每個(gè)區(qū)域的大小。
  • Memory Graph顯示應(yīng)用程序使用的內(nèi)存的位置精盅,以及這些使用內(nèi)存之間的引用關(guān)系帽哑。

3.如何使用Memory Graph

打開配置

注意點(diǎn):

  1. 啟用Malloc Stack后,Memory Graph會(huì)顯示分配該節(jié)點(diǎn)時(shí)記錄的堆棧跟蹤叹俏。使用此信息將Memory Graph中的內(nèi)存分配與源代碼中的函數(shù)和方法相關(guān)聯(lián)妻枕。如果沒(méi)有勾選 Malloc Stack 在調(diào)試的時(shí)候,在右側(cè)是看不到調(diào)用的堆棧信息。

  2. 勾選 Malloc Stack 之后內(nèi)存會(huì)相應(yīng)的增高屡谐,如果不調(diào)試可以關(guān)閉該選項(xiàng)述么。

  3. 建議選擇 Live Allocations Only 如果選擇 All Allocations and Free History 會(huì)出現(xiàn)一些額外的影響因素。

打開方式

通過(guò)單擊Xcode工作區(qū)底部調(diào)試區(qū)域中的 Debug Memory Graph 按鈕來(lái)生成應(yīng)用程序中對(duì)象和分配的內(nèi)存圖愕掏。

點(diǎn)擊`Debug Memory Graph`暫停應(yīng)用執(zhí)行度秘,展示如下:
  • 在左側(cè)debug navigator展示了app的heap contents
  • 在中間部分是對(duì)象的引用關(guān)系饵撑。
  • 在最右側(cè)是展示了當(dāng)前對(duì)象的調(diào)用椊J幔回溯。

Memory Graph顯示應(yīng)用程序正在使用的內(nèi)存區(qū)域以及每個(gè)區(qū)域的大小滑潘。圖中的節(jié)點(diǎn)代表一個(gè)對(duì)象(object)垢乙、一個(gè)堆分配(heap allocation)或內(nèi)存映射文件(memory-mapped file)。節(jié)點(diǎn)之間的連接语卤,通過(guò)箭頭連接追逮,顯示一個(gè)內(nèi)存區(qū)域引用另一個(gè)對(duì)象。

Tips:

為了幫助我們更快的分析內(nèi)存泄漏粹舵,我們可以在左側(cè)的debug navigator進(jìn)行篩選只展示leaks的內(nèi)容羊壹。

可以將我們生成的memory graph進(jìn)行導(dǎo)出,選擇 file > export Memory Graph 共享給團(tuán)隊(duì)內(nèi)的人員使用和分析探索齐婴。我們還可以使用命令行工具進(jìn)行分析油猫,主要的指令有leaksheap柠偶、vmmap情妖、malloc_history等。

4.項(xiàng)目實(shí)際應(yīng)用及分析

導(dǎo)出所對(duì)應(yīng)的Memory Graph使用命令行的形式進(jìn)行分析诱担。主要分析內(nèi)存泄漏大內(nèi)存占用毡证。

Memory FootPrint


Apple推薦我們使用FootPrint命令查看一個(gè)進(jìn)程占用的大小。關(guān)于什么是 footprint蔫仙,在官方文檔 Minimizing your app’s Memory Footprint 里有說(shuō)明:

FootPrint =  Dirty memory + Swapped memory(Compressed memory)
Refers to the total current amount of system memory that is allocated to your app.

iOS中內(nèi)存分為兩種:

  • Clean memory

    • 內(nèi)存映射文件(Memory mapped files )
    • 數(shù)據(jù)段常量/代碼段數(shù)據(jù) (System Frameworks)
  • Dirty memory

    • (堆上分配的內(nèi)存) All heap allocations

    • (解碼圖像緩沖區(qū)) Decoded image buffers

    • Frameworks

      Clean memory在系統(tǒng)內(nèi)存緊張的時(shí)候可以從page中換出料睛,當(dāng)再次訪問(wèn)的時(shí)候可以從磁盤中進(jìn)行讀取。Dirty memory是無(wú)法換出的

在iOS7時(shí)Apple引入了Compressed memory 摇邦,即系統(tǒng)可以把最近最少使用的Dirty memory進(jìn)行壓縮恤煞,這樣可以騰出一些pages供使用,當(dāng)再次需要訪問(wèn)內(nèi)容時(shí)施籍,系統(tǒng)將其解壓居扒,這時(shí),原來(lái)內(nèi)容占多少pages丑慎,解壓后同樣會(huì)是相同數(shù)量的pages

1.內(nèi)存分析

先通過(guò)vmmap看一下內(nèi)存的摘要圖:

    vmmap -summary memGraph.memgraph
  • 從這個(gè)圖中可以看到當(dāng)前app的一個(gè)內(nèi)存分布情況喜喂,footPrint占用的內(nèi)存大小為26.1M瓤摧,根據(jù)footprint的計(jì)算方式可以知道,我們需要關(guān)注的是dirty size + swapped size這兩列的數(shù)據(jù)玉吁。首先看下對(duì)應(yīng)的Region type分別代表的是什么內(nèi)存照弥。

    • CG raster data(光柵化數(shù)據(jù),也就是像素?cái)?shù)據(jù)进副。注意不一定是圖片产喉,一塊顯示緩存里也可能是文字或者其他內(nèi)容。通常每像素消耗 4 個(gè)字節(jié))
    • Image IO敢会、IOSurface(圖片編解碼緩存)
    • maclloc_ 開頭的是我們自己通過(guò)malloc進(jìn)行創(chuàng)建的內(nèi)存占用曾沈。這部分內(nèi)存在所謂的Heap上。
    • IOSurface 在CoreGraphics鸥昏、OpenGLES塞俱、Metal之間傳遞紋理數(shù)據(jù)。簡(jiǎn)單理解為IOSurface吏垮,為CPU和GPU直接搭建了?個(gè)傳遞紋理數(shù)據(jù)的橋梁障涯。

那么看下具體的是哪些類占用了內(nèi)存。需要具體來(lái)分析一下膳汪。

從里面看到都是CG raster data 占用比較大唯蝶。具體在哪里被引用了,需要看一下具體的調(diào)用棧遗嗽。首先篩選出來(lái)CG raster data的內(nèi)存信息粘我,包括它的地址、尺寸以及所在Heap Zone等等信息痹换。我們可以在這里找到我們的目標(biāo)征字。

vmmap memGraph.memgraph |  grep 'CG raster data'

malloc_history -fullStacks memGraph.memgraph 0x10ee24000

通過(guò)vmmap 篩除所有關(guān)于CG raster data內(nèi)存情況。然后通過(guò)malloc_history -fullStacks拿到對(duì)象的詳細(xì)調(diào)用堆棧娇豫。

可以看出是在SDWebImage對(duì)圖片的解碼數(shù)據(jù)做了緩存匙姜。建議在使用的時(shí)候設(shè)置緩存的圖片數(shù)量和大小。也可以根據(jù)具體的情況關(guān)掉解碼的緩存冯痢〉粒或者在加載大圖的時(shí)候使用ImageIO的形式進(jìn)行加載。

2.內(nèi)存泄漏

通過(guò)leaks篩除所有的內(nèi)存泄漏

leaks memGraph.memgraph

從上圖中可以看出浦楣,是AFHttpSessionManager出現(xiàn)了內(nèi)存泄漏袖肥,從引用的關(guān)系中可以看出,是當(dāng)前的sessionManager強(qiáng)引用了session椒振,sessiondelegate同時(shí)強(qiáng)引用了sessionManager昭伸。解決方案就是我們?cè)谡{(diào)用之前使用weak弱引用sessionManager梧乘,當(dāng)請(qǐng)求完成的時(shí)候執(zhí)行finishTasksAndInvalidate澎迎。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末庐杨,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子夹供,更是在濱河造成了極大的恐慌灵份,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哮洽,死亡現(xiàn)場(chǎng)離奇詭異填渠,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)鸟辅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門氛什,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人匪凉,你說(shuō)我怎么就攤上這事枪眉。” “怎么了再层?”我有些...
    開封第一講書人閱讀 169,461評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵贸铜,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我聂受,道長(zhǎng)蒿秦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,135評(píng)論 1 300
  • 正文 為了忘掉前任蛋济,我火速辦了婚禮棍鳖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘碗旅。我一直安慰自己鹊杖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評(píng)論 6 398
  • 文/花漫 我一把揭開白布扛芽。 她就那樣靜靜地躺著骂蓖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪川尖。 梳的紋絲不亂的頭發(fā)上登下,一...
    開封第一講書人閱讀 52,736評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音叮喳,去河邊找鬼被芳。 笑死,一個(gè)胖子當(dāng)著我的面吹牛馍悟,可吹牛的內(nèi)容都是我干的畔濒。 我是一名探鬼主播,決...
    沈念sama閱讀 41,179評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼锣咒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼侵状!你這毒婦竟也來(lái)了赞弥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,124評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤趣兄,失蹤者是張志新(化名)和其女友劉穎绽左,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體艇潭,經(jīng)...
    沈念sama閱讀 46,657評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拼窥,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蹋凝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鲁纠。...
    茶點(diǎn)故事閱讀 40,872評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鳍寂,靈堂內(nèi)的尸體忽然破棺而出房交,到底是詐尸還是另有隱情,我是刑警寧澤伐割,帶...
    沈念sama閱讀 36,533評(píng)論 5 351
  • 正文 年R本政府宣布候味,位于F島的核電站,受9級(jí)特大地震影響隔心,放射性物質(zhì)發(fā)生泄漏白群。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評(píng)論 3 336
  • 文/蒙蒙 一硬霍、第九天 我趴在偏房一處隱蔽的房頂上張望帜慢。 院中可真熱鬧,春花似錦唯卖、人聲如沸粱玲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)抽减。三九已至,卻和暖如春橄碾,著一層夾襖步出監(jiān)牢的瞬間卵沉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工法牲, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留史汗,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,304評(píng)論 3 379
  • 正文 我出身青樓拒垃,卻偏偏與公主長(zhǎng)得像停撞,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子悼瓮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容