Allocations:检测一个进程(选择自己的app)内存分配和使用情况等

我们启动Allocations后得到一个初始界面

初始界面.png

简单说一下上图的3个地方

1:这里有两个部分了,因为官方说了Allocations(上面)和垃圾数据占用(下面)一起展示更好分析

2:一个列表,展示了哪些方法\部分消耗了多少内存,前面的钩钩上会在1部分显示出主柱状图,自己点一下就知道了,不截图

3:设置和扩展功能,文章后面慢慢讲

开始分析列表

我先随意的在自己app中点击,跳转等操作,然后截个图如下

分析图.png

我们可以惊讶的看到All Heap Allocations(真实内存)只有23.02,而All Anonymous VM(虚拟内存:为程序分配的虚拟内存,当程序有需要的时候,能够及时为程序提供足够的内存空间,而不会现用现创建)高达91.06,所以手机分配给我们的内存是114.08;我们现在不检测内存泄漏(是另外一个工具),所以我们尽量优化VM(因为不是app真实占用的内存,只是系统分配的),而VM主要由以下三部分组成(我会把三部分都优化完了后再运行截图)

VM:ImageIO_PNG_Data

关于这个问题我在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,确实有很多地方使用了,所以我们加载图片正确的思路应该是这样

1:对于大的图片且偶尔需要显示的应放到工程目录下,不要放到Assets.xcassets中;并使用imageWithContentsOfFile加载不让系统缓存
2:对于经常需要展示的小图片放到Assets.xcassets中让系统缓存,使用imageNamed加载

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

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

VM:CG raster data

关于这个问题我在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中设置一下

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

VM:CoreAnimation

这个问题在google搜索的时候没有明显的答案,我们先查看一下详细列表

进入详情列表.png

我们可以看到很多的地方都有这个VM问题,那我们具体看一下是哪些函数

具体查看调用栈.png

我们可以发现都是系统的一些方法,我们好像无从下手;这时候我们可以google看看发现有很多原因都会变成这个样子,其中一个是 这里

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我们还是需要在扩展信息中查看能不能定位到某个页面(我不知道怎么定位,如果你知道请一定回复我),所以我在我刚才进入过的界面全部实现了如上方法

看看优化结果

这时候我们重新启动Allocations,然后重复上面随意的在自己app中点击,跳转等操作,然后截图如下

VM优化结果.png

我们发现一个好的现象VM:CG raster data明显减少了;同时我们得到一个坏现象,其他两项并没有明显变化,那我们继续分析什么原因,不过不要着急,我们先来看看右下方都有哪些功能

Record Settings

Launch Configuration for All Allocations

所有的Allocations启动如下配置:

Discard unrecorded data upon stop:当用户点击停止的时候丢弃没有记录的数据,勾不勾无所谓

Discard events for freed memory:当内存被释放的时候丢弃事件(也就是列表中不显示已被释放内存所关联的事件)

Only track VM allocations:只捕获虚拟内存的项,不勾,因为我们还是需要看看真实内存占用的

这里我们需要把第一、二个勾上

Launch Configuration for Heap Allocations

对所有的真实内存Allocations启动如下配置(如果你钩中了Only track VM allocations,这一栏是没办法操作的):

Record reference counts:记录引用计数

Identity virtual C++ objects:标记虚拟c++对象,这个钩上可以检测openGL等库

Enable NSZombie detection:检测僵尸对象,钩上可以发现有没有对已释放的对象发送消息

Recorded Types

这个我就不需要解释了,你需要捕获什么类型的事件就钩上,提供了简单的正则

Dispalay Settings

Track Display

决定上面将要显示什么内容

上面显示什么内容.png

Current Bytes:显示字节数量

Allocation Density:Allocation数量

Active Allocation Distribution:新激活的Allocation数量

Generation Analysis

这个功能是非常有用的,一般是这样用的:进入一个页面前mark一下,在退出这个页面的时候再mark一下可以比较哪些内容增加了,就可以具体分析哪些内存没有被释放;比如我们要进入日程界面的时候我点了一下mark

列表自动切换了.png

显示了Growth(相比上一次增加的量)为27.48,也就是第一次真实内存和虚拟内存之和;我们在日程界面操作一阵子之后我们再点击mark截图

再次mark.png

所以我们知道了我们退出日程界面内存依然还是增加了2.85,你可以点击查看具体是哪些增加了

哪些增加了.png

Allocation Lifespan

需要记录哪些Allocation

All Allocations:所有的

Created & Persistent:创建且存活的

Created & Destroyed:创建且被销毁的

我们目前只关心存活的,所以我们钩上第二个

Allocation Type

记录的Allocation类型

All Heap & Anonymous VM:所有真实内存和虚拟内存,我通常选这个分析

All Heap Allocations:所有真实内存

All VM Regions:所有分配过的虚拟内存

这里的选择将会影响到列表,比如我选择All VM Regions

只显示虚拟内存.png

Call Tree

这里的功能需要我们把列表展示类型切换成Call Trees,能够非常清晰的看到调用树

调用树展示.png

不过一般我们需要勾选一些选项,因为默认的实在看不出什么东西

Separate by Category:按照类别隔开,我们钩上看看效果

按照类别隔开.png

瞬间好看多了,我们能够清楚的看出来是哪些类别的VM

Separate by Thread:按照线程划分,我个人不是很喜欢这种划分,因为我不是很关心线程

Invert Call Tree:反转调用,我们给一张对比图就不需要解释了

未钩中.png

钩中.png

我习惯钩上,因为我能够一眼看到具体哪个方法出现了问题

Hide System Libraries:这个似乎是必钩的,因为我们目前只关心自己的方法,不关心系统的

Flatten Recursion:扁平化递归,我暂时还不知道是干嘛的,网上也没有搜到,不过我还是钩上了,听着是一个不错的功能

Call Tree Constraints

这个我就不需要讲了,是对列表中的数据进行过滤,可以是数量和大小;比如我只关心100以内的数据

100之内的数据png

Data Mining

数据挖掘,这是一个很具有噱头的功能; 官网 给了这么一个解释

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

就是可以过滤掉你不看的库、符号调用

点击Symbol、Library会自动把你选中的行的符号、库加到小框中

例子.png

符号和库有两个选项,就是是否过滤改行;点击Restore会去掉小框中的选中行,比如我们把帮帮管理助手去掉

去掉某行.png

我觉得我暂时用不到数据挖掘,所以我后面熟悉了的时候再来补充这部分

Extended Detail

这个我其实已经介绍过了,对于Allocations来说是看某一条数据的调用栈等信息

到现在我们只有一种列表展示没有介绍了,我们来看一眼

Allocations List类型.png

相对于Statistics来说多了调用库和方法的展示

继续优化

刚才说到了,我们只对VM:CG raster data的优化表示满意,接下来我们继续优化VM:CoreAnimation和VM:ImageIO_PNG_Data

VM:ImageIO_PNG_Data优化

前面说到我们把加载大图片的方法换成了imageWithContentsOfFile但是效果不明显,现在我们就来看看具体是哪个方法产生了大量的虚拟内存,下面是步骤

查看列表

找到调用函数.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

优化VM:CoreAnimation

我们同样用Generations检测出了这个问题

内存增加的主要内容.png

前面说到我们谷歌到可以采用下面的方法减少

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

但是证明几乎没用,那我们只好继续谷歌看看,按照上面的方法,我们在谷歌输入关键字CA::Render::Shmem::new_shmem(unsigned long)进行搜索,我们从搜索的结果可以得知这是一个很多原因都会导致的结果;其中在 这篇文章 有两段描述

the solution is to reduce that space to an absolute minimum.
//把控件的范围设置到最小
...
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优化是一个大问题,可能需要一篇文章单独讲

看另一部分

接下来我们来看看这个视图是干什么用的,使用的时候需要手动捕获(或者你钩上Automatic Snapshotting自动定时捕获)一次左下角列表才有数据

捕获一次.png

默认会显示三种数据

Dirty Size:脏数据大小(没办法被重复使用)

Swapped Size:交换空间大小

Resident Size:固定数据大小

关于这三个名字的解释,你可以看看这里,所以我们得知这条数据是有异常的

异常数据.png

因为产生了31.54的垃圾数据,我们在 这里 找到了想要的答案,结果证明无效

又从 这里 得知我们不需要管这个问题,因为这时XCode工具自身的,不是我们程序的

所以我们来看下一个问题

下一个问题.png

我还特别重新启动了一次,证明我确实没有做什么其他操作,结果垃圾数据还是很多

malloc开头的.png

这是为什么呢?答案在 这里 ,所以这一部分我们也不需要管,所以我们的程序没有出现大量垃圾数据情况,问题还是出在CoreAnimation

CoreAnimation问题.png

我们把这个问题留着, 因为和上面优化VM:CoreAnimation是一类问题,等我熟悉了我再补充

Regoins Map

Regoins Map视图.png

这个视图,主要是把每一条数据的地址段和调用路径给你显示出来了,我很少用这个视图,不过能看到path还是不错的

Allocations一般来做什么

其实文本已经大致讲了一下,Allocations对app优化非常有用,通常是拿来分析内存增加(不一定是内存泄漏)和app中各部分占用内存问题,当我们得知哪个内存占用比较多,我们直接进行优化即可减少内存占用问题

Instruments学习之Allocations的更多相关文章

  1. Instruments学习之Core Animation学习

    当App发展到一定的规模,性能优化就成为必不可少的一点.但是很多人,又对性能优化很陌生,毕竟平常大多时间都在写业务逻辑,很少关注这个.最近在优化自己的项目,也收集了很多资料,这里先浅谈一下使用Inst ...

  2. 如何使用Instruments诊断App(Swift版):起步-b

    无论你写过许多iOS应用,还是刚刚开始你的第一个应用,毫无疑问,你都会想出一些新点子,或者想去弄明白你该怎么做,来让你的app变得更好. 除去添加新特性来优化你的应用,有一件事是所有好的开发者都回去做 ...

  3. iOS的内存分析和内存管理

    iOS的内存分析和内存管理 [内存管理]一直是iOS开发中的一个重点. 本文就带你从内存分析开始一步步了解内存的占用情况,从真实的情况中领悟真正项目开发过程中的内存的使用情况. 注:本文默认你熟悉 M ...

  4. Instruments之Leaks学习

    前言: 本篇文章,在于学习,我把别人的一些感觉好的文章汇总成了一篇,亲自实现了一下,留用于今后学习资料. 文章脉络:文章脉络: 一.内存优化 简介:Objective_C 有3种内存管理方法, 它们分 ...

  5. GopherCon SG 2019 "Understanding Allocations" 学习笔记

    本篇是根据 GopherCon SG 2019 "Understanding Allocations" 演讲的学习笔记. Understanding Allocations: th ...

  6. Instruments 使用指南

    Instruments 用户指南 http://cdn.cocimg.com/bbs/attachment/Fid_6/6_24457_90eabb4ed5b3863.pdf 原著:Apple Inc ...

  7. JProfiler学习笔记

    JProfiler学习笔记   一.安装JProfiler        从http://www.ej-technologies.com/下载5.1.2并申请试用序列号   二.主要功能简介 1.内存 ...

  8. 离屏渲染学习笔记 /iOS圆角性能问题

    离屏渲染学习笔记 一.概念理解 OpenGL中,GPU屏幕渲染有以下两种方式: On-Screen Rendering 意为当前屏幕渲染,指的是GPU的渲染操作是在当前用于显示的屏幕缓冲区中进行. O ...

  9. iOS系类教程之用instruments来检验你的app

    比较了好多关于instruments 还是发现老外写的比较牛逼.于是果断翻译过来.有能力的的可以去看英文原版,鼓励大家看原版资料远离二手教程.这里是原文   入门 为了节省大家的时间,提供一个演示的D ...

随机推荐

  1. Atitit xml框架类库选型 attilax总结

    Atitit xml框架类库选型 attilax总结 1. 1. XML类库可以分成2大类.标准的.这些类库通常接口和实现都是分开的1 2. Jdom 和dom4j1 2.1. 5.1. jdom1 ...

  2. python prettytable模块

    简介 Python通过PrettyTable模块可以将输出内容如表格方式整齐地输出. 安装 pip install prettytable 1 示例 from prettytable import P ...

  3. [APM] 解读APM技术分类和实现方式

    在讲了APM的历史.作用和实际案例之后,下面我们来了解一下APM技术分类和实现方式以及它未来的发展趋势.在这之前,我们首先需要了解一下典型的互联网或移动互联网应用的整个应用交付链. 图1 上面这张示意 ...

  4. 【Java】分布式RPC通信框架Apache Thrift 使用总结

    简介 Apache Thrift是Facebook开源的跨语言的RPC通信框架,目前已经捐献给Apache基金会管理,由于其跨语言特性和出色的性能,在很多互联网公司得到应用,有能力的公司甚至会基于th ...

  5. hdoj:2044

    #include <iostream> using namespace std; long long fib(int n) { ; ; ) ; ) { long long f2 = f0 ...

  6. Java知多少(13)流程控制

    Java流程控制的语法与 C/C++ 类似,也有 if...else.while.do...while.for.switch...case等,这里不再讲述具体语法,仅举例说明. 输出九九乘法表(右上三 ...

  7. Image Lazy Load:那些延时加载图片的开源插件(jQuery)

    图片延时加载技术对大流量的网站来说是十分实用的.目前图片在网站中大量使用,如果不加处理的话会对服务器和带宽造成级大压力,通过只渲染当前用户可见区域的图片,可以极大地减少网站的请求数,降低网络带宽资源. ...

  8. Scala学习笔记——函数式对象

    用创建一个函数式对象(类Rational)的过程来说明 类Rational是一种表示有理数(Rational number)的类 package com.scala.first /** * Creat ...

  9. System.Runtime.InteropServices.COMException 检索COM类工厂中CLSID{xxxxxxxxx}的组件时失败解决方法

    iis7.5中设定应用程序池中<进程模型>中<标识>为localSystem 提示:System.Runtime.InteropServices.COMException: 命 ...

  10. [Artoolkit] ARToolKit's SDK Structure on Android

    Most applications on Android are developed in Java, and Android provides a rich framework of classes ...