Instruments學(xué)習(xí)之Allocations

注意:這個工具非常有用,文本也是一個超長文

Allocations初始界面

Allocations:檢測一個進程(選擇自己的app)內(nèi)存分配和使用情況等
我們啟動Allocations后得到一個初始界面


初始界面.png

簡單說一下上圖的3個地方
1:這里有兩個部分了臭挽,因為官方說了Allocations(上面)和垃圾數(shù)據(jù)占用(下面)一起展示更好分析
2:一個列表捂襟,展示了哪些方法\部分消耗了多少內(nèi)存,前面的鉤鉤上會在1部分顯示出主柱狀圖欢峰,自己點一下就知道了葬荷,不截圖
3:設(shè)置和擴展功能,文章后面慢慢講

開始分析列表

我先隨意的在自己app中點擊纽帖,跳轉(zhuǎn)等操作宠漩,然后截個圖如下


分析圖.png

我們可以驚訝的看到All Heap Allocations(真實內(nèi)存)只有23.02,而All Anonymous VM(虛擬內(nèi)存:為程序分配的虛擬內(nèi)存,當程序有需要的時候懊直,能夠及時為程序提供足夠的內(nèi)存空間扒吁,而不會現(xiàn)用現(xiàn)創(chuàng)建)高達91.06,所以手機分配給我們的內(nèi)存是114.08室囊;我們現(xiàn)在不檢測內(nèi)存泄漏(是另外一個工具)雕崩,所以我們盡量優(yōu)化VM(因為不是app真實占用的內(nèi)存,只是系統(tǒng)分配的)融撞,而VM主要由以下三部分組成(我會把三部分都優(yōu)化完了后再運行截圖)

VM:ImageIO_PNG_Data

關(guān)于這個問題我在google中找到了解釋盼铁,說到

Replace:
background.image = [UIImage imageNamed:@"*.png"];
With:
background.image = [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/*.png"]];
and now the ImageIO_PNG_Data's will be released when the view controller is dismissed.

我后面在我工程中搜索了一下imageNamed,確實有很多地方使用了尝偎,所以我們加載圖片正確的思路應(yīng)該是這樣

1:對于大的圖片且偶爾需要顯示的應(yīng)放到工程目錄下饶火,不要放到Assets.xcassets中鹏控;并使用imageWithContentsOfFile加載不讓系統(tǒng)緩存
2:對于經(jīng)常需要展示的小圖片放到Assets.xcassets中讓系統(tǒng)緩存,使用imageNamed加載

所以我改了一些地方肤寝,比如

imageView.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:nameArr[index] ofType:@"png"]];
//imageView.image = [UIImage imageNamed:nameArr[index]];

VM:CG raster data

關(guān)于這個問題我在google中找到了解釋当辐,這是SDWebImage的問題

* Decompressing images that are downloaded and cached can improve peformance but can consume lot of memory.
* Defaults to YES. Set this to NO if you are experiencing a crash due to excessive memory consumption.

所以我們需要在Appdelegate中設(shè)置一下

[[SDImageCache sharedImageCache] setShouldDecompressImages:NO];
[[SDWebImageDownloader sharedDownloader] setShouldDecompressImages:NO];
[[SDImageCache sharedImageCache] setShouldCacheImagesInMemory:NO];

VM:CoreAnimation

這個問題在google搜索的時候沒有明顯的答案,我們先查看一下詳細列表

進入詳情列表.png
我們可以看到很多的地方都有這個VM問題醒陆,那我們具體看一下是哪些函數(shù)
具體查看調(diào)用棧.png
我們可以發(fā)現(xiàn)都是系統(tǒng)的一些方法瀑构,我們好像無從下手;這時候我們可以google看看發(fā)現(xiàn)有很多原因都會變成這個樣子刨摩,其中一個是這里

Found out that animation caused by the inner pages.
Inside the pageViewController(viewController that added to the scrollView as a page) on viewWillDisappear:(BOOL)animated method I added this
for (CALayer* layer in [self.view.layer sublayers]) {
        [layer removeAllAnimations];
}
it resolved the problem.

其中的Found out that animation caused by the inner pages我們還是需要在擴展信息中查看能不能定位到某個頁面(我不知道怎么定位寺晌,如果你知道請一定回復(fù)我),所以我在我剛才進入過的界面全部實現(xiàn)了如上方法

看看優(yōu)化結(jié)果

這時候我們重新啟動Allocations澡刹,然后重復(fù)上面隨意的在自己app中點擊呻征,跳轉(zhuǎn)等操作,然后截圖如下


VM優(yōu)化結(jié)果.png

我們發(fā)現(xiàn)一個好的現(xiàn)象VM:CG raster data明顯減少了罢浇;同時我們得到一個壞現(xiàn)象陆赋,其他兩項并沒有明顯變化,那我們繼續(xù)分析什么原因嚷闭,不過不要著急攒岛,我們先來看看右下方都有哪些功能

Record Settings

Launch Configuration for All Allocations

所有的Allocations啟動如下配置:
Discard unrecorded data upon stop:當用戶點擊停止的時候丟棄沒有記錄的數(shù)據(jù),勾不勾無所謂
Discard events for freed memory:當內(nèi)存被釋放的時候丟棄事件(也就是列表中不顯示已被釋放內(nèi)存所關(guān)聯(lián)的事件)
Only track VM allocations:只捕獲虛擬內(nèi)存的項胞锰,不勾灾锯,因為我們還是需要看看真實內(nèi)存占用的
這里我們需要把第一、二個勾上

Launch Configuration for Heap Allocations

對所有的真實內(nèi)存Allocations啟動如下配置(如果你鉤中了Only track VM allocations嗅榕,這一欄是沒辦法操作的):
Record reference counts:記錄引用計數(shù)
Identity virtual C++ objects:標記虛擬c++對象顺饮,這個鉤上可以檢測openGL等庫
Enable NSZombie detection:檢測僵尸對象,鉤上可以發(fā)現(xiàn)有沒有對已釋放的對象發(fā)送消息

Recorded Types

這個我就不需要解釋了凌那,你需要捕獲什么類型的事件就鉤上兼雄,提供了簡單的正則

Dispalay Settings

Track Display

決定上面將要顯示什么內(nèi)容


上面顯示什么內(nèi)容.png

Current Bytes:顯示字節(jié)數(shù)量
Allocation Density:Allocation數(shù)量
Active Allocation Distribution:新激活的Allocation數(shù)量

Generation Analysis

這個功能是非常有用的,一般是這樣用的:進入一個頁面前mark一下帽蝶,在退出這個頁面的時候再mark一下可以比較哪些內(nèi)容增加了赦肋,就可以具體分析哪些內(nèi)存沒有被釋放;比如我們要進入日程界面的時候我點了一下mark


列表自動切換了.png

顯示了Growth(相比上一次增加的量)為27.48嘲碱,也就是第一次真實內(nèi)存和虛擬內(nèi)存之和金砍;我們在日程界面操作一陣子之后我們再點擊mark截圖


再次mark.png
所以我們知道了我們退出日程界面內(nèi)存依然還是增加了2.85,你可以點擊查看具體是哪些增加了
哪些增加了.png

Allocation Lifespan

需要記錄哪些Allocation
All Allocations:所有的
Created & Persistent:創(chuàng)建且存活的
Created & Destroyed:創(chuàng)建且被銷毀的
我們目前只關(guān)心存活的麦锯,所以我們鉤上第二個

Allocation Type

記錄的Allocation類型
All Heap & Anonymous VM:所有真實內(nèi)存和虛擬內(nèi)存恕稠,我通常選這個分析
All Heap Allocations:所有真實內(nèi)存
All VM Regions:所有分配過的虛擬內(nèi)存
這里的選擇將會影響到列表,比如我選擇All VM Regions


只顯示虛擬內(nèi)存.png

Call Tree

這里的功能需要我們把列表展示類型切換成Call Trees扶欣,能夠非常清晰的看到調(diào)用樹


調(diào)用樹展示.png

不過一般我們需要勾選一些選項鹅巍,因為默認的實在看不出什么東西
Separate by Category:按照類別隔開千扶,我們鉤上看看效果


按照類別隔開.png
瞬間好看多了,我們能夠清楚的看出來是哪些類別的VM
Separate by Thread:按照線程劃分骆捧,我個人不是很喜歡這種劃分澎羞,因為我不是很關(guān)心線程

Invert Call Tree:反轉(zhuǎn)調(diào)用,我們給一張對比圖就不需要解釋了


未鉤中.png

鉤中.png
我習(xí)慣鉤上敛苇,因為我能夠一眼看到具體哪個方法出現(xiàn)了問題
Hide System Libraries:這個似乎是必鉤的妆绞,因為我們目前只關(guān)心自己的方法,不關(guān)心系統(tǒng)的
Flatten Recursion:扁平化遞歸枫攀,我暫時還不知道是干嘛的括饶,網(wǎng)上也沒有搜到,不過我還是鉤上了来涨,聽著是一個不錯的功能

Call Tree Constraints

這個我就不需要講了图焰,是對列表中的數(shù)據(jù)進行過濾,可以是數(shù)量和大斜钠技羔;比如我只關(guān)心100以內(nèi)的數(shù)據(jù)


100之內(nèi)的數(shù)據(jù)png

Data Mining

數(shù)據(jù)挖掘,這是一個很具有噱頭的功能卧抗;官網(wǎng)給了這么一個解釋

Allows you to filter through the collected data for specific symbols and libraries.

就是可以過濾掉你不看的庫藤滥、符號調(diào)用
點擊Symbol、Library會自動把你選中的行的符號社裆、庫加到小框中


例子.png

符號和庫有兩個選項超陆,就是是否過濾改行;點擊Restore會去掉小框中的選中行浦马,比如我們把幫幫管理助手去掉
去掉某行.png
我覺得我暫時用不到數(shù)據(jù)挖掘,所以我后面熟悉了的時候再來補充這部分

Extended Detail

這個我其實已經(jīng)介紹過了张漂,對于Allocations來說是看某一條數(shù)據(jù)的調(diào)用棧等信息
到現(xiàn)在我們只有一種列表展示沒有介紹了晶默,我們來看一眼


Allocations List類型.png

相對于Statistics來說多了調(diào)用庫和方法的展示

繼續(xù)優(yōu)化

剛才說到了,我們只對VM:CG raster data的優(yōu)化表示滿意航攒,接下來我們繼續(xù)優(yōu)化VM:CoreAnimation和VM:ImageIO_PNG_Data

VM:ImageIO_PNG_Data優(yōu)化

前面說到我們把加載大圖片的方法換成了imageWithContentsOfFile但是效果不明顯磺陡,現(xiàn)在我們就來看看具體是哪個方法產(chǎn)生了大量的虛擬內(nèi)存,下面是步驟

查看列表

找到調(diào)用函數(shù).png
在谷歌借鑒了解決方法

//_pageScrollView是一個滾動視圖漠畜,用來加載本地圖片
...
//加入圖片
    for (int index = 0; index < nameArr.count; index ++) {
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(index * pageScrollImagewidth, 0, pageScrollImagewidth, pageScrollImageheight)];
         NSString *imageFile = [NSString stringWithFormat:@"%@/%@.png",[[NSBundle mainBundle] resourcePath],nameArr[index]];
        @autoreleasepool {
             imageView.image = [UIImage imageWithContentsOfFile:imageFile];
        }
//        imageView.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:nameArr[index] ofType:@"png"]];
//        imageView.image = [UIImage imageNamed:nameArr[index]];
        [_pageScrollView addSubview:imageView];
    }
...
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    for (UIView *viewView in _pageScrollView.subviews) {
        [viewView removeFromSuperview];
    }
    _pageScrollView = nil;
}

按照這個方法后币他,效果還是很明顯的,之前是33.95(看文章前面的圖)


減少了很多.png

優(yōu)化VM:CoreAnimation

我們同樣用Generations檢測出了這個問題


內(nèi)存增加的主要內(nèi)容.png

前面說到我們谷歌到可以采用下面的方法減少

for (CALayer *layer in self.view.layer.sublayers) {
        [layer removeAllAnimations];
    }

但是證明幾乎沒用憔狞,那我們只好繼續(xù)谷歌看看蝴悉,按照上面的方法,我們在谷歌輸入關(guān)鍵字CA::Render::Shmem::new_shmem(unsigned long)進行搜索瘾敢,我們從搜索的結(jié)果可以得知這是一個很多原因都會導(dǎo)致的結(jié)果拍冠;其中在這篇文章有兩段描述

the solution is to reduce that space to an absolute minimum.
//把控件的范圍設(shè)置到最小
...
I am having the same issue. I will try what you suggested with the size. 
But, maybe changing the background color from clearColor could 
correct the issue as well.
//改變視圖的背景顏色

我試了改變背景顏色尿这,沒什么作用

[[UIView appearance] setBackgroundColor:[UIColor whiteColor]];
[[UIView appearance] setBackgroundColor:[UIColor clearColor]];

所以我們就暫時不解決這個了,我后面解決了會在這里進行補充庆杜,VM:Animation優(yōu)化是一個大問題射众,可能需要一篇文章單獨講

看另一部分

接下來我們來看看這個視圖是干什么用的,使用的時候需要手動捕獲(或者你鉤上Automatic Snapshotting自動定時捕獲)一次左下角列表才有數(shù)據(jù)

捕獲一次.png
默認會顯示三種數(shù)據(jù)
Dirty Size:臟數(shù)據(jù)大谢尾啤(沒辦法被重復(fù)使用)
Swapped Size:交換空間大小
Resident Size:固定數(shù)據(jù)大小
關(guān)于這三個名字的解釋叨橱,你可以看看這里,所以我們得知這條數(shù)據(jù)是有異常的
異常數(shù)據(jù).png
因為產(chǎn)生了31.54的垃圾數(shù)據(jù)断盛,我們在這里找到了想要的答案罗洗,結(jié)果證明無效
又從這里得知我們不需要管這個問題,因為這時XCode工具自身的郑临,不是我們程序的
所以我們來看下一個問題
下一個問題.png
我還特別重新啟動了一次栖博,證明我確實沒有做什么其他操作,結(jié)果垃圾數(shù)據(jù)還是很多
malloc開頭的.png
這是為什么呢厢洞?答案在這里仇让,所以這一部分我們也不需要管,所以我們的程序沒有出現(xiàn)大量垃圾數(shù)據(jù)情況躺翻,問題還是出在CoreAnimation
CoreAnimation問題.png
我們把這個問題留著丧叽, 因為和上面優(yōu)化VM:CoreAnimation是一類問題,等我熟悉了我再補充

Regoins Map

Regoins Map視圖.png

這個視圖公你,主要是把每一條數(shù)據(jù)的地址段和調(diào)用路徑給你顯示出來了踊淳,我很少用這個視圖,不過能看到path還是不錯的

Allocations一般來做什么

其實文本已經(jīng)大致講了一下陕靠,Allocations對app優(yōu)化非常有用迂尝,通常是拿來分析內(nèi)存增加(不一定是內(nèi)存泄漏)和app中各部分占用內(nèi)存問題,當我們得知哪個內(nèi)存占用比較多剪芥,我們直接進行優(yōu)化即可減少內(nèi)存占用問題
本文一直在討論如何減少VM的占用垄开,你接下來可以分析Heap占用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市税肪,隨后出現(xiàn)的幾起案子溉躲,更是在濱河造成了極大的恐慌,老刑警劉巖益兄,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锻梳,死亡現(xiàn)場離奇詭異,居然都是意外死亡净捅,警方通過查閱死者的電腦和手機疑枯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蛔六,“玉大人神汹,你說我怎么就攤上這事庆捺。” “怎么了屁魏?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵滔以,是天一觀的道長。 經(jīng)常有香客問我氓拼,道長你画,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任桃漾,我火速辦了婚禮坏匪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘撬统。我一直安慰自己适滓,他們只是感情好,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布恋追。 她就那樣靜靜地躺著凭迹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪苦囱。 梳的紋絲不亂的頭發(fā)上嗅绸,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機與錄音撕彤,去河邊找鬼鱼鸠。 笑死,一個胖子當著我的面吹牛羹铅,可吹牛的內(nèi)容都是我干的蚀狰。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼职员,長吁一口氣:“原來是場噩夢啊……” “哼造锅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起廉邑,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎倒谷,沒想到半個月后蛛蒙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡渤愁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年牵祟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抖格。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡诺苹,死狀恐怖咕晋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情收奔,我是刑警寧澤掌呜,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站坪哄,受9級特大地震影響质蕉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜翩肌,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一模暗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧念祭,春花似錦兑宇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至比规,卻和暖如春若厚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工瘩缆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留悯搔,地道東北人。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓霎冯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親钞瀑。 傳聞我的和親對象是個殘疾皇子沈撞,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350

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

  • 轉(zhuǎn)載地址:http://gnucto.blog.51cto.com/3391516/998509 Redis與Me...
    Ddaidai閱讀 21,446評論 0 82
  • 學(xué)習(xí)如何使用【Xcode Instruments】來進行錯誤排查和優(yōu)化代碼。 更新提示:這篇教程由James Fr...
    汝陰龍閱讀 1,248評論 0 1
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,846評論 25 707
  • 還記得與你初識的那個冬天雕什,那時的我正值心情不好缠俺,獨在異鄉(xiāng),一個剛剛走出校門贷岸,走上工作崗位的女孩壹士,吃住都在單位,條...
    月映禪心閱讀 415評論 0 0
  • 春,以她的盎然生機、秀麗撫媚動人心弦盒使;夏崩掘,以她的熱情奔放、熾熱強悍激人奮進少办;秋苞慢,以她的豪爽瀟灑、輝煌成熟奪人魂魄...
    巴黎左岸zhy閱讀 982評論 0 4