iOS与内存管理

内存工具


针对iOS开发,我们所能使用的内存排查工具选择其实并不算特别多。最主要的调试工具就是Instruments。然而,如果仔细探查细节,Instruments还是集成了很多不错的调试模板/Library的。


本文针对如下几类应用场景,对通用的调试方法做基本介绍:


  • 最基本最常用的内存问题场景——内存泄露、过度释放

  • malloc相关的堆内存分配问题排查相关工具

  • 其它内存工具


1. 内存泄露与过度释放


我们应该都知道,iOS开发过程中,使用Objective-C分配的堆内存都是通过引用计数来做保留和释放的。一块内存初始分配,引用计数为1,此后每新增一个强引用,引用计数增加1;释放正好相反,每一次release,引用计数减1,直到为0,对象所用内存被真正free掉,以被再次复用。然而,实际开发当中,总有一些原因导致引用计数无法按正常逻辑减少到0,或者减少到0之后仍然被调用release,前者是内存泄露,后者则是过度释放。


当内存泄露发生时,运行的App不会直接第发生明显问题,但废弃内存得不到回收,在长时间持续运行后,App进程会由于可用内存不断变低而被kill或带来其它隐患。


避免内存泄露,首要是有良好的代码习惯,避免循环引用、会用weak,其次可以通过Analyze来进行静态代码检查,以发现在语法上显而易见的内存泄露问题。但更多时候,内存泄露是运行时的问题,这时可用Instruments中的Allocation和Leaks来不断重复操作App,发现和定位内存泄露点。


当运行时发生显示内存泄露时,Leaks会在时间轴上标出红色指示线,同时在Instruments的下方会列出调用细节,结合系统提供的malloc历史,其中包含引用计数变化情况,以及调用栈可以很直接地找到泄露原因。


同时对于一些“隐式”的情况,需要反复操作,同时观察Allocation中只增不减,一直创建新对象而不释放老对象的情况。


过度释放,是对同一个对象释放了过多的次数,其实当引用计数降到0时,对象占用的内存已经被释放掉,此时指向原对象的指针就成了“悬垂指针”,如若再对其进行任何方法的调用,(原则上)都会直接crash(然而由于某些特殊的情况,不会马上crash)。


对于这种问题,可以直接使用Zombie,当过度释放发生时会立即停在发生问题的位置,同时结合内存分配释放历史和调用栈,可以发现问题。


至于上文提到的不会crash的原因,其实有很多,比如:


  • 对象内存释放时,所用内存并没有完全被擦除,仍有旧对象部分数据可用

  • 原内存位置被写入同类或同样结构的数据


2. malloc库提供的相关工具


上一段提到,对象释放时,所用内存并没有完全被擦除,仍有旧对象部分数据可用,如果不使用Zombie调试,App可能不会直接crash。对付这种情况,其实很简单,可以在对象内存释放时写入无意义数据,如0×55,0xaa等,而系统已经帮我们做了这个工具,那就是Scribble,在Xcode的Edit Scheme里,Diagnostics Tab下勾选Enable Scribble。


Scribble其实是malloc库(libsystem_malloc.dylib)自身提供的调试方案,除了Scribble,malloc还提供了很多其它的调试工具/方案,在Diagnostics Tab下你应该都看到了。其实,malloc可用的工具还不止这些,通过环境变量至少还可以添加如下调试参数:


  • MallocLogFile

  • MallocGuardEdges

  • MallocDoNotProtectPrelude

  • MallocDoNotProtectPostlude

  • StackLogging

  • StackLoggingNoCompact

  • MallocCorruptionAbort

  • MallocNanoZone

  • MallocCheckHeap


其中,有几个参数是和记录分配历史的日志有关的。


除此之外,Xcode里还提供了Guard malloc,这个是等同于默认malloc库功能的另外一个调试库,为了定位大内存越界访问问题,不过只能在模拟器上使用(个人分析是因为真机根本承受不起保护页内存消耗)。


对以上参数的实现细节感兴趣的,可以参看苹果开放出来的malloc源码。


3. 其它


下面我还想对Instruments里的三样东西做简要介绍:


  • Allocation

  • Activity Monitor

  • VM Tracker


Allocation针对堆内存及匿名映射的情况提供了详细的数据,包括某类对象有多少个,对象的具体地址,占用多大内存等。通过Allocation,可以对我们开发中实际接触到的内存有非常全面的把握。


Activity Monitor则从系统的层面,对主要进程的CPU、内存、网络等数据做分析。从内存方面看,我们可以知道占用系统内存最大的5个App,它提供的数据包含了实际物理内存和虚拟内存部分。


VM Tracker则可以告诉我们哪些部分是Dirty的,Dirty的数据系统不会直接清理掉,因为这些数据是被写过的,无法通过外部存储直接生成,只能维持在内存当中。此外,通过VM Tracker我们还可以看到Region Map,看到进程地址空间各部分的映射情况。



除了上面提到的这些,对于诡异的内存问题,我们可以对Xcode7中的Address Sanitizer期待和试用下,也许它真得能帮我们解决好多问题!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: iOS内存管理版本记录如下: 1. iOS 2.0及更早版本:使用手动管理内存的方式。 2. iOS 3.0:引入了基于引用计数的自动内存管理,使用retain和release函数来增加或减少对象的引用计数。 3. iOS 5.0:引入了ARC(自动引用计数)机制,ARC会在编译时自动插入retain和release代码,减少手动管理内存的工作。 4. iOS 7.0:引入了内存诊断工具Memory Usage Report,可以监测App内存使用情况,帮助开发者优化内存管理。 5. iOS 8.0:引入了一些新的API,如NSCache和NSURLSession,使得内存管理更加方便和灵活。 6. iOS 11.0:引入了基于图片大小的UIImage渲染机制,减少了内存占用。 7. iOS 13.0:引入了叫做“Scene”的多任务环境,使得内存管理更加复杂,需要更加小心谨慎地处理内存问题。 总的来说,随着iOS版本的不断更新,内存管理的机制也在不断地完善和优化,使得iOS应用能够更加高效地使用内存,提高用户体验。 ### 回答2: iOS内存管理是由操作系统自动管理的,在不同的版本中有所不同。 在iOS 5之前的版本中,内存管理主要依赖于手动管理引用计数(reference counting)来管理对象的生命周期。开发者需要手动调用retain和release方法来增加或减少对象的引用计数,以确保对象在不再需要时能够被正确释放。这种方式需要开发者非常谨慎地管理对象的引用,以避免内存泄漏或野指针等问题。 从iOS 5开始,iOS引入了自动引用计数(Automatic Reference Counting,ARC)的内存管理机制。ARC可以自动地插入retain、release和autorelease等方法的调用,使得开发者不再需要手动进行内存管理。开发者只需要关注对象的创建和使用,而不需要关心具体的内存管理细节。ARC减少了内存管理的工作量,提高了开发效率,并且减少了内存泄漏和野指针等问题的发生。不过,ARC并不是完全的自动化内存管理,开发者仍然需要遵循一些规则,比如避免循环引用等,以保证内存的正确释放。 随着iOS版本的不断更新,苹果不断改进和优化内存管理机制。每个新版本都带来了更好的性能和更高效的内存管理。开发者可以通过关注苹果的官方文档和开发者社区中的更新内容来了解每个版本中的具体变化和改进。 总结来说,iOS内存管理从手动的引用计数到自动引用计数的演变,极大地简化了开发者的工作,并提高了应用的性能和稳定性。随着不断的改进和优化,iOS内存管理会越来越高效和可靠。 ### 回答3: iOS内存管理版本记录是指苹果公司在不同版本的iOS操作系统中对于内存管理方面的改进和更新记录。随着iOS版本的不断迭代,苹果在内存管理方面进行了一系列的优化和改进,以提高系统的稳定性和性能。 首先,在早期的iOS版本中,苹果采用了手动内存管理的方式,即开发人员需要手动创建和释放内存,容易出现内存泄漏和内存溢出等问题。为了解决这些问题,苹果在iOS5版本中引入了自动引用计数(ARC)机制。ARC机制能够通过编译器自动生成内存管理代码,避免了手动管理内存带来的问题。 其次,iOS6版本引入了内存分页机制。这个机制能够将应用程序内存分成不同的页,将不常用的页置于闲置列表中,从而释放出更多的内存空间。这些闲置列表中的页能够在需要时快速恢复到内存中,减少了内存压力。 此外,iOS7版本中进一步提升了内存管理的能力。苹果在这个版本中引入了内存压缩技术,将内存中的数据进行压缩,从而提高了内存利用率。此外,iOS7还引入了资源清理功能,可以自动清理不再使用的资源,释放内存空间。 最后,在iOS13版本中,苹果进一步改进了内存管理策略。该版本中引入了后台内存优化功能,能够自动优化应用在后台运行时的内存占用,减少了后台应用对于系统内存的占用和影响。 综上所述,iOS内存管理版本记录反映了苹果在不同版本的iOS操作系统中对于内存管理方面的改进和优化。这些改进和优化使得iOS系统更加稳定和高效,并且提升了应用程序的性能和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值