iOS内存分析之Memory Graph

1.Memory Graph是什么

Memory Graph是在Xcode8上推出的一个新特性。用来生成运用程序中目标分配的内存图。

2.Memory Graph用来做什么

  • Memory Graph能够协助咱们找到循环引证和内存走漏,正在运用的内存以及每个区域的巨细。
  • Memory Graph显现运用程序运用的内存的位置,以及这些运用内存之间的引证联系。

3.如何运用Memory Graph

打开装备

iOS内存分析之Memory Graph

注意点:

  1. 启用Malloc Stack后,Memory Graph会显现分配该节点时记载的仓库盯梢。运用此信息将Memory Graph中的内存分配与源代码中的函数和方法相关联。如果没有勾选 Malloc Stack 在调试的时分,在右侧是看不到调用的仓库信息。

  2. 勾选 Malloc Stack 之后内存会相应的增高,如果不调试能够关闭该选项。

  3. 主张挑选 Live Allocations Only 如果挑选 All Allocations and Free History 会呈现一些额外的影响因素。

打开方法

经过单击Xcode工作区底部调试区域中的 Debug Memory Graph 按钮来生成运用程序中目标和分配的内存图。

iOS内存分析之Memory Graph

​ 点击Debug Memory Graph暂停运用履行,展现如下:

iOS内存分析之Memory Graph

  • 在左边debug navigator展现了app的heap contents
  • 在中间部分是目标的引证联系。
  • 在最右侧是展现了当前目标的调用栈回溯。

Memory Graph显现运用程序正在运用的内存区域以及每个区域的巨细。图中的节点代表一个目标(object)、一个堆分配(heap allocation)或内存映射文件(memory-mapped file)。节点之间的连接,经过箭头连接,显现一个内存区域引证另一个目标。

iOS内存分析之Memory Graph

Tips:

为了协助咱们更快的剖析内存走漏,咱们能够在左边的debug navigator进行筛选只展现leaks的内容。

iOS内存分析之Memory Graph

能够将咱们生成的memory graph进行导出,挑选 file > export Memory Graph 共享给团队内的人员运用和剖析探索。咱们还能够运用指令行东西进行剖析,首要的指令有leaksheapvmmapmalloc_history等。

iOS内存分析之Memory Graph

4.项目实践运用及剖析

导出所对应的Memory Graph运用指令行的方法进行剖析。首要剖析内存走漏大内存占用。

Memory FootPrint


Apple推荐咱们运用FootPrint指令查看一个进程占用的巨细。关于什么是 footprint,在官方文档 Minimizing your app’s Memory Footprint 里有阐明:

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

iOS中内存分为两种:

  • Clean memory

    • 内存映射文件(Memory mapped files )
    • 数据段常量/代码段数据 (System Frameworks)
  • Dirty memory

    • (堆上分配的内存) All heap allocations

    • (解码图像缓冲区) Decoded image buffers

    • Frameworks

      Clean memory在体系内存严重的时分能够从page中换出,当再次访问的时分能够从磁盘中进行读取。Dirty memory是无法换出的

在iOS7时Apple引入了Compressed memory ,即体系能够把最近最少运用的Dirty memory进行紧缩,这样能够腾出一些pages供运用,当再次需求访问内容时,体系将其解压,这时,本来内容占多少pages,解压后同样会是相同数量的pages

1.内存剖析

先经过vmmap看一下内存的摘要图:

    vmmap -summary memGraph.memgraph

iOS内存分析之Memory Graph

iOS内存分析之Memory Graph

iOS内存分析之Memory Graph

  • 从这个图中能够看到当前app的一个内存散布状况,footPrint占用的内存巨细为26.1M,根据footprint的计算方法能够知道,咱们需求重视的是dirty size + swapped size这两列的数据。首要看下对应的Region type别离代表的是什么内存。

    • CG raster data(光栅化数据,也便是像素数据。注意纷歧定是图片,一块显现缓存里也可能是文字或许其他内容。通常每像素消耗 4 个字节)
    • Image IOIOSurface(图片编解码缓存)
    • maclloc_ 最初的是咱们自己经过malloc进行创立的内存占用。这部本分存在所谓的Heap上。
    • IOSurface 在CoreGraphics、OpenGLES、Metal之间传递纹路数据。简略理解为IOSurface,为CPU和GPU直接搭建了⼀个传递纹路数据的桥梁。

那么看下具体的是哪些类占用了内存。需求具体来剖析一下。

从里面看到都是CG raster data 占用比较大。具体在哪里被引证了,需求看一下具体的调用栈。首要筛选出来CG raster data的内存信息,包括它的地址、尺度以及所在Heap Zone等等信息。咱们能够在这里找到咱们的目标。

vmmap memGraph.memgraph |  grep 'CG raster data'
malloc_history -fullStacks memGraph.memgraph 0x10ee24000

经过vmmap 筛除所有关于CG raster data内存状况。然后经过malloc_history -fullStacks拿到目标的具体调用仓库。

iOS内存分析之Memory Graph

能够看出是在SDWebImage对图片的解码数据做了缓存。主张在运用的时分设置缓存的图片数量和巨细。也能够根据具体的状况关掉解码的缓存。或许在加载大图的时分运用ImageIO的方法进行加载。

2.内存走漏

经过leaks筛除所有的内存走漏

leaks memGraph.memgraph

iOS内存分析之Memory Graph

从上图中能够看出,是AFHttpSessionManager呈现了内存走漏,从引证的联系中能够看出,是当前的sessionManager强引证了sessionsessiondelegate一起强引证了sessionManager。解决方案便是咱们在调用之前运用weak弱引证sessionManager,当恳求完成的时分履行finishTasksAndInvalidate

iOS内存分析之Memory Graph