热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Instruments学习之Allocations

Allocations:检测一个进程(选择自己的app)内存分配和使用情况等我们启动Allocations后得到一个初始界面初始界面.pn

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 &#61; 0; index < nameArr.count; index &#43;&#43;) { UIImageView *imageView &#61; [[UIImageView alloc] initWithFrame:CGRectMake(index * pageScrollImagewidth, 0, pageScrollImagewidth, pageScrollImageheight)]; NSString *imageFile &#61; [NSString stringWithFormat:&#64;"%&#64;/%&#64;.png",[[NSBundle mainBundle] resourcePath],nameArr[index]]; &#64;autoreleasepool { imageView.image &#61; [UIImage imageWithContentsOfFile:imageFile]; } // imageView.image &#61; [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:nameArr[index] ofType:&#64;"png"]]; // imageView.image &#61; [UIImage imageNamed:nameArr[index]]; [_pageScrollView addSubview:imageView]; } ... - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; for (UIView *viewView in _pageScrollView.subviews) { [viewView removeFromSuperview]; } _pageScrollView &#61; nil; }

按照这个方法后&#xff0c;效果还是很明显的&#xff0c;之前是33.95&#xff08;看文章前面的图&#xff09;

减少了很多.png

优化VM:CoreAnimation

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

内存增加的主要内容.png

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

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

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

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. //改变视图的背景颜色

我试了改变背景颜色&#xff0c;没什么作用

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

所以我们就暂时不解决这个了&#xff0c;我后面解决了会在这里进行补充&#xff0c;VM:Animation优化是一个大问题&#xff0c;可能需要一篇文章单独讲

看另一部分

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

捕获一次.png

默认会显示三种数据

Dirty Size&#xff1a;脏数据大小&#xff08;没办法被重复使用&#xff09;

Swapped Size&#xff1a;交换空间大小

Resident Size&#xff1a;固定数据大小

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

异常数据.png

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

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

所以我们来看下一个问题

下一个问题.png

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

malloc开头的.png

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

CoreAnimation问题.png

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

Regoins Map

Regoins Map视图.png

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

Allocations一般来做什么

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

转:https://www.cnblogs.com/lxlx1798/p/6933195.html



推荐阅读
  • Android源码中的Builder模式及其作用
    本文主要解释了什么是Builder模式以及其作用,并结合Android源码来分析Builder模式的实现。Builder模式是将产品的设计、表示和构建进行分离,通过引入建造者角色,简化了构建复杂产品的流程,并且使得产品的构建可以灵活适应变化。使用Builder模式可以解决开发者需要关注产品表示和构建步骤的问题,并且当构建流程发生变化时,无需修改代码即可适配新的构建流程。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • Oracle10g备份导入的方法及注意事项
    本文介绍了使用Oracle10g进行备份导入的方法及相关注意事项,同时还介绍了2019年独角兽企业重金招聘Python工程师的标准。内容包括导出exp命令、删用户、创建数据库、授权等操作,以及导入imp命令的使用。详细介绍了导入时的参数设置,如full、ignore、buffer、commit、feedback等。转载来源于https://my.oschina.net/u/1767754/blog/377593。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
author-avatar
xiaobin
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有