1.Memory Graph是什么
Memory Graph
是在Xcode8
上推出的一个新特性。用来生成运用程序中目标分配的内存图。
2.Memory Graph用来做什么
-
Memory Graph
能够协助咱们找到循环引证和内存走漏,正在运用的内存以及每个区域的巨细。 -
Memory Graph
显现运用程序运用的内存的位置,以及这些运用内存之间的引证联系。
3.如何运用Memory Graph
打开装备
注意点:
-
启用
Malloc Stack
后,Memory Graph
会显现分配该节点时记载的仓库盯梢。运用此信息将Memory Graph
中的内存分配与源代码中的函数和方法相关联。如果没有勾选Malloc Stack
在调试的时分,在右侧是看不到调用的仓库信息。 -
勾选
Malloc Stack
之后内存会相应的增高,如果不调试能够关闭该选项。 -
主张挑选
Live Allocations Only
如果挑选All Allocations and Free History
会呈现一些额外的影响因素。
打开方法
经过单击Xcode
工作区底部调试区域中的 Debug Memory Graph
按钮来生成运用程序中目标和分配的内存图。
点击Debug Memory Graph
暂停运用履行,展现如下:
- 在左边
debug navigator
展现了app的heap contents
。 - 在中间部分是目标的引证联系。
- 在最右侧是展现了当前目标的调用栈回溯。
Memory Graph
显现运用程序正在运用的内存区域以及每个区域的巨细。图中的节点代表一个目标(object
)、一个堆分配(heap allocation
)或内存映射文件(memory-mapped file
)。节点之间的连接,经过箭头连接,显现一个内存区域引证另一个目标。
Tips:
为了协助咱们更快的剖析内存走漏,咱们能够在左边的debug navigator
进行筛选只展现leaks的内容。
能够将咱们生成的memory graph进行导出,挑选 file
> export Memory Graph
共享给团队内的人员运用和剖析探索。咱们还能够运用指令行东西进行剖析,首要的指令有leaks
、heap
、vmmap
、malloc_history
等。
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
-
从这个图中能够看到当前app的一个内存散布状况,
footPrint
占用的内存巨细为26.1M,根据footprint
的计算方法能够知道,咱们需求重视的是dirty size + swapped size
这两列的数据。首要看下对应的Region type
别离代表的是什么内存。- CG raster data(光栅化数据,也便是像素数据。注意纷歧定是图片,一块显现缓存里也可能是文字或许其他内容。通常每像素消耗 4 个字节)
- Image IO、IOSurface(图片编解码缓存)
- 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
拿到目标的具体调用仓库。
能够看出是在SDWebImage对图片的解码数据做了缓存。主张在运用的时分设置缓存的图片数量和巨细。也能够根据具体的状况关掉解码的缓存。或许在加载大图的时分运用ImageIO
的方法进行加载。
2.内存走漏
经过leaks筛除所有的内存走漏
leaks memGraph.memgraph
从上图中能够看出,是AFHttpSessionManager
呈现了内存走漏,从引证的联系中能够看出,是当前的sessionManager
强引证了session
,session
的delegate
一起强引证了sessionManager
。解决方案便是咱们在调用之前运用weak弱引证sessionManager
,当恳求完成的时分履行finishTasksAndInvalidate
。