面试题答案
一键面试使用Instruments工具检测内存泄漏的具体步骤:
- 打开Instruments:在Xcode菜单栏中选择“Xcode” -> “Open Developer Tool” -> “Instruments”。
- 选择模板:在弹出的“Instruments”窗口中,选择“Leaks”模板,该模板专门用于检测内存泄漏问题。然后点击“Choose”按钮。
- 选择目标应用:如果你的设备已经连接并且应用已安装在设备上,在Instruments左上角的设备列表中选择你的设备以及要分析的应用。如果是模拟器运行的应用,同样在列表中选择对应的模拟器及应用。
- 开始记录:点击Instruments界面中的红色圆形录制按钮,开始运行应用并记录内存使用情况。
- 操作应用:在应用运行过程中,模拟各种用户操作场景,尽量覆盖应用的各个功能模块,以确保潜在的内存泄漏情况能够被触发。例如,多次打开和关闭视图控制器、反复加载和卸载数据等操作。
- 停止记录:完成操作后,点击Instruments界面中的黑色方形停止按钮,停止记录。此时,Instruments会对记录的数据进行分析,并展示内存泄漏相关的信息。
解读Instruments工具生成的内存泄漏报告:
- Leaks列表:在Instruments的主窗口中,“Leaks”面板会列出检测到的所有内存泄漏情况。每一行代表一个泄漏的内存块,包括以下关键信息:
- Address:泄漏内存块的地址。
- Size:泄漏内存块的大小,以字节为单位。较大的泄漏内存块通常需要优先关注,因为它们对应用性能的影响可能更大。
- Responsible Library:导致内存泄漏的库或框架。通常如果是自己的应用代码导致的泄漏,这里会显示应用的名称;如果是系统库导致的,会显示相应的系统库名称。在分析泄漏原因时,需要重点查看自己应用代码导致的泄漏情况。
- Responsible Caller:导致内存泄漏的函数调用。这是定位内存泄漏代码位置的重要线索,通过查看该函数调用,可以追溯到具体是哪段代码在分配内存后没有正确释放。
- Call Tree:在“Instruments”窗口的下方,切换到“Call Tree”视图。这里展示了导致内存泄漏的函数调用堆栈。通过展开各个函数节点,可以看到函数之间的调用关系。从顶部的函数开始,逐步向下查找,确定在哪个函数中分配了内存但未释放。重点关注那些分配内存的函数(如
alloc
、malloc
等),以及可能没有正确平衡内存释放的地方。 - Heapshot:Heapshot是Instruments中的一个功能,用于拍摄应用内存堆的快照。在检测内存泄漏时,可以通过Heapshot对比不同时间点的内存堆状态,观察哪些对象的数量在不断增加,而没有相应的减少,这很可能是内存泄漏的迹象。在Leaks面板中,点击某个泄漏的内存块,然后在右侧的详细信息区域中,可能会看到“Heapshot”相关的按钮或链接,点击它们可以查看对应的Heapshot信息。
- Object Graph:Object Graph以图形化的方式展示对象之间的引用关系。对于复杂的内存泄漏场景,通过查看Object Graph可以更好地理解对象之间的相互引用情况,确定是否存在循环引用导致的内存泄漏。在Leaks面板中选中泄漏的内存块后,在右侧详细信息区域可能会找到“Object Graph”相关选项,点击可查看对象图。如果发现对象之间形成了循环引用环,就需要在代码中打破这种循环引用,例如通过设置弱引用(
weak
)来解决。