几个iOS的内存检测工具memtest工具粗略介绍

内存优化工具介绍 - 简书
内存优化工具介绍
内存泄漏(Memory Leaks)是当一个对象或变量在使用完成后没有释放掉,这个对象一直占有着这块内存,直到应用停止。如果这种对象过多内存就会耗尽,其它的应用就无法运行。这个问题在C++、C和Objective-C的MRR中是比较普遍的问题。在Objective-C中释放对象的内存是发送release和autorelease消息,它们都是可以将引用计数减1,当为引用计数为0时候,release消息会使对象立刻释放,autorelease消息会使对象放入内存释放池中延迟释放。理论上讲内 存泄漏是对象或变量没有释放引起的,但实践证明并非所有的未释放对象或变量都会导致内存泄漏,这与硬件环境和操作系统环境有关,因此我们需要检测工具帮助 我们找到这些“泄漏点”。在Xcode中提供了两种工具帮助查找泄漏点:Analyze和Profile,Analyze是静态分析工具可以通过菜单 Product→Analyze启动,为静态分析之后的代码画面;Profile是动态分析工具,这个工具叫“Instruments”,它是Xcode 集成在一起,可以在Xcode中通过菜单Product→Profile启动,Instruments有很多Trace Template(跟踪模板)可以动态分析和跟踪内存、CPU和文件系统。我们可以两个工具结合使用查找泄漏点,先使用Analyze静态分析查找可疑泄漏点,再用Profile动态分析中的Leaks和Allocations跟踪模板进行动态跟踪分析,确认这些点是否泄漏,或者是否有新的泄漏出现等。事实上内存泄漏是极其复杂问题,工具使用是一方面,经验是另一方面。提高经验,然后借助于工具才是解决内存泄漏的根本。参考链接:(http://blog.csdn.net/xdrt81y/article/details/)作者:蔡哲永如果问题,请加QQ,备注写解决问题,和我单独沟通哦。
没有最好,只有更好!
内存优化: Objective_C 有3种内存管理方法, 它们分别是
MRR (Manual Retain Release, 手动保持释放), ARC(Automatic Reference Counting, 自动引用计数) 和 GC(Garbage Collectio...
性能对于一款app来说至关重要,而程序的内存占用情况就是一项很重要的性能指标。虽然iOS 5.0版本之后加入了ARC机制,但由于相互引用关系比较复杂时,内存泄露还是可能存在。文章脉络: 一、内存优化简介:Objective_C 有3种内存管理方法, 它们分别是 MRR (M...
前言: 本篇文章,在于学习,我把别人的一些感觉好的文章汇总成了一篇,亲自实现了一下,留用于今后学习资料。 文章脉络: 一、内存优化 简介:Objective_C 有3种内存管理方法, 它们分别是- MRR (Manual Retain Release, 手动保持释放)- A...
先来一发苹果官网上Instruments User Guide,其实没啥用,英语不好的也懒得去看。(反正我是看不懂) 关于Instruments有网友如是说的:“一句话: 内存开销、运行速度、内存泄露 and so on”。 如此简单的回答肯定打发不了咱们各位看官和面试官,...
一、Analyze【静态分析】 XCode Product——&Analyze 或者 command+shift+B Analyze的作用: 1、逻辑错误:访问空指针或未初始化的变量等; 2、内存管理错误:如内存泄漏等; 3、声明错误:从未使用过的变量; 4、Api调用错误...
很多人都认为,睡觉是最好的休息方式。不,它不是,睡眠只在特定的时候睡才能帮我们补充体力、精力,缓解身体上的疲惫。 为什么说睡眠不是 最近我观察到一个现象;在我的周围,很多人(包括我在内)都有午睡的习惯,不过是有的人睡得久一点,有的人谁的短一点;比如我自己,我午睡一般就20分...
卡片1 小学一年级的你,爸妈指着新闻联播上的天安门,调侃你,「以后去北大上学好不好?」你一脸认真的问,「那岂不是得每天坐飞机上学啊?」也许你没想到,多年后的自己,真的成功的考到了北京的大学,虽然不是北大,而是与它齐名的隔壁。我不会再担心怎么上学的问题,只是我很怀念,那段每天...
《改变你的服装,改变你的生活》 如何通过改变服装重新定义自己,变成更好的自己。 (1)升级自我认知 买衣服前照镜子,并问自己两个问题。 001我的身体特征是什么? 留心身材的优势和不足。 002我想给人留下什么印象? 在镜子前要问自己,不是穿这件衣服是否还可以,而是它能给人...
(本文写于) 日晚上七点钟,我们班的情报员A小李私下微信跟我汇报情况时候,添加了一句:“老师,建议你要尽快将小明(化名)和小东(化名)换位!我今天发现小东被小明用笔戳得手脚都是伤,看着就恶心。!” 我收到信息后询问:“小明为什么要用笔...
原文 Active or Passive 活跃 or 消极 Constructive or Indolent 积极 or 懒惰iOS 典型内存泄露案例 - zhenshan2013的个人空间 - 51Testing软件测试网 51Testing软件测试网-中国软件测试人的精神家园
欢迎测试探讨
iOS 典型内存泄露案例
& 17:02:55 / 天气: 热
/ 心情: 平静
/ 个人分类:
&& &最近进行iOS 安全黑匣子的,在Demo中通过不断的点击调加密接口,同时通过自带instrument的leak工具监控,发现典型的内存泄漏,监控图如下:& &&上图中红色的部分表示该操作触发的代码有内存泄漏的可能,于是拿出源代码来研究一番,源代码如下:&//加密接口-(IBAction)encrypt:(id)sender {& &&out&=& &&NSString&*text =&@"taobao://?ssoType=AuthorizeApplicationPrefix&appkey=1234&appName=SSO Demo&urlSchemes=ssodemo://&t=";& & NSData&*inputData = [text&dataUsingEncoding:NSUTF8StringEncoding];& &&out&= [[[TBSecretMgr sharedInstance] encrypt:inputData]retain];& &&NSString&*test =[[NSString&alloc]&initWithData:out&encoding:NSUTF8StringEncoding];& &NSLog(@"encrypt:%@",test);& &[test&release];}//解密接口- (IBAction)deEncrypt:(id)sender {& &&NSData&*deEncryptOut = [[TBSecretMgr&sharedInstance]&decrypt:out];& &&NSString&*outStr = [[NSString&alloc]&initWithData:deEncryptOut&encoding:NSUTF8StringEncoding];& &&NSLog(@"deencry%@",outStr);& &&[outStr&release];}在分析这2个接口之前,我们需要了解iOS的内存机制,尤其对基本的alloc,retain,release,dealloc需要理解.&alloc &对象分配后引用计数为1retain 对象的引用计数+1copy & copy一个对象变成新的对象(新内存地址)引用计数为1,原来对象计数不变.relase 对象引用计数-1,如果为0释放内存autorelase 对象引用计数-1,如果为0不马上释放.内存管理的原则就是最终的引用计数要平衡.如果最后引用计数大于0,则会内存泄漏如果引用计数等于0还对该对象进行操作,则会出现内存访问失败,crash.此段代码out返回类型是Nsstring,后加一个retain,在不断的点击下,每次引用,都会retain+1,而没有release操作,导致内存一直被占用,没有释放. 解决方案就是把加解密放在一个操作中,不加retain计数.代码修改如下,内存泄漏问题解决:- (IBAction)encrypt:(id)sender {out =NSString *text =NSData *inputData = [text dataUsingEncoding:NSUTF8StringEncoding];out = [[TBSecretMgr sharedInstance] encrypt:inputData];NSString *test =[[NSString alloc] initWithData:out encoding:NSUTF8StringEncoding];NSLog(@"encrypt:%@",test);[test release];NSData *deEncryptOut = [[TBSecretMgr sharedInstance] decrypt:out];NSString *outStr = [[NSString alloc] initWithData:deEncryptOut encoding:NSUTF8StringEncoding];NSLog(@"Dencry%@",outStr);[outStr release];}iOS 爆内存问题解决方案-OOMDetector 组件 - 腾讯开源 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
已注册用户请 &
iOS 爆内存问题解决方案-OOMDetector 组件 - 腾讯开源
· 162 天前 · 884 次点击
OOMDetector 是手 Q 自研的 IOS 内存监控组件,腾讯内部目前已有多个 App 接入了 OOMDetector,它主要有以下两个功能:
爆内存堆栈统计:负责记录进程内存分配堆栈和内存块大小,在爆内存时 Dump 堆栈数据到磁盘
内存泄漏检测:检测内存泄漏,目前支持 Malloc 内存块和 OC 对象的泄漏检测
OOMDetector 可以快速帮助开发者发现和定位 App 爆内存问题和内存泄漏,组件目前已经在 Github 开源,源码地址:
目前业内已有一些比较的 IOS 内存分析工具,下面逐个介绍这些工具的功能以及它们在使用上的不足。
Allocation
作为 IOS 开发,我们都很熟悉苹果官方提供的 Allocation 内存分析工具,在开发调试阶段,可以用 Allocation 详细分析 App 各模块内存占用。Allocation 对 App 的内存监控比较全面,能监控到所有堆内存以及部分 VM 内存分配。虽然 Allocation 的功能比较强大,但是它也有比较明显的使用局限性,主要表现为以下两点:
无法独立在 App 运行,只能在调试阶段连接 Mac 使用
性能较差,大型 App 开启后容易引发卡死
这两点限制决定了 Allocation 只适合于在开发阶段辅助分析代码中存在的内存问题,而无法直接对线上用户的问题进行监控和定位。
FBAllocationTracker
FBAllocationTracker 是 Facebook 开源的内存分析工具,它的原理是用 Method Swizzling 替换原本的 alloc 方法,这样可以在 App 运行时记录所有 OC 实例的分配信息,帮助 App 在运行阶段发现一些 OC 对象的异常增长问题。相比 Allocation,FBAllocationTracker 对 App 性能影响较低,可以在 App 中独立运行。但是这个工具也有比较明显的缺陷:
监控范围不够全面,只能监控 OC 对象,不能监控 C++对象和 malloc 内存块以及 VM 内存
没有内存对象分配的堆栈信息,对于开发者来说很难只通过对象的类型和数量定位到内存增长的原因
综上所述,FBAllocationTracker 虽然能独立在 App 中运行,但是监控的内存范围太小,同时记录的对象信息也过于简单,对于分析内存问题帮助十分有限。
内存问题一直是手 Q 的关注重点,为了保证线上大盘用户的内存质量,我们希望有一款工具能够帮助监控和定位线上用户的内存问题。基于这样的背景,我们团队自研了 OOMDetector 组件。OOMDetector 通过 Hook 系统底层的内存分配方法,能够记录到进程所有内存分配的堆栈信息,同时组件能够在对性能流畅度影响不大的情况下能够保证在 App 中独立运行,可以方便用于分析和监控线上用户的内存问题(爆内存或者内存泄漏问题)。
爆内存堆栈统计
爆内存堆栈监控原理
爆内存堆栈监控的实现原理如图 1 所示,通过 Hook IOS 系统底层内存分配的相关方法(包括 malloc_zone 相关的堆内存分配以及 vm_allocate 对应的 VM 内存分配方法),跟踪并记录进程中每个对象内存的分配信息,包括分配堆栈、累计分配次数、累计分配内存等,这些信息也会被缓存到进程内存中。在内存触顶的时候,组件会定时 Dump 这些堆栈信息到本地磁盘,这样如果程序爆内存了,就可以将爆内存前 Dump 的堆栈数据上报到后台服务器进行分析。
图 1 爆内存监控原理
App 的内存分配方法的调用频率非常高,在大型 App 中可能高达 10W/次每秒。要 Hook 这类方法对组件的性能来说是极大的挑战,因为如果组件本身耗时的话就很容易导致 App 卡顿甚至卡死。在 OOMDetector 中,我们对 Hook 方法代码的执行效率进行了严格控制,也采取了一些策略对 Hook 方法中耗时较多的堆栈回溯和锁等待进行了优化:
优化堆栈回溯方法
对于堆栈回溯,系统提供了 backtrace_symbols 方法可以直接获取堆栈信息,但是这个方法特别耗时。所以我们根据堆栈的回溯原理实现了更高效的堆栈回溯方法,优化后的方法在运行时只会获取堆栈函数的地址信息,在回写磁盘的时候再根据动态库的地址范围拼装成如图 2 所示堆栈格式(类似 Crash 堆栈),后台服务器利用 atos 命令和符号表文件就可以还原出对应的堆栈内容。通过这种方式可以把耗时较高的符号还原工作放到服务器端,客户端只需要执行耗时较少的堆栈函数地址回溯操作,优化后的堆栈回溯方法耗时低于 1us。
图 2 堆栈格式
优化锁等待耗时
对于多线程的内存分配,为了保证线程安全,堆栈数据的插入操作必须要上锁。对于这种高频调用的方法,锁的性能是我们最关心的指标。IOS 开发中 NSLock 和 @synchronized 是比较常用的,那么这两种锁的性能如何呢?
我们通过测试代码对 IOS 中常用的锁进行了测试,总结了图 2 所示的各种锁的性能比较图,根据图 3 的测试结果,NSLock 和 @synchronized 的性能要低于 pthread_mutex,性能最好的是自旋锁 OSSpinLock。
自旋锁的原理是,如果自旋锁已经被别的执行单元保持,调用者就一直循环等待锁的释放。相比互斥锁而言,自旋锁不会引起调用者休眠,节省了线程休眠的状态切换,所以有更高的效率,但代价是增加了 cpu 的使用率。对于我们的场景,因为需要上锁部分的代码执行耗时较少,采用 OSSpinLock 的自旋锁并不会显著增加 cpu 的使用率,所以我们优先考虑锁的效率采用了 OSSpinLock 的方案。
图 3 各种锁的性能比较
堆栈聚类和压缩
之前提到,我们的 Hook 方法会缓存每个内存分配的堆栈数据。假设 App 的内存块个数为 25W,堆栈平均深度 20 行,每个堆栈地址采用 8 字节的整型数据存储,那么 25W 个堆栈数据将占用 40M 的内存空间。显然这样的内存增长对于任何 App 都是不可承受的,所以我们需要对组件的内存占用进行优化。
我们分析爆内存问题时候,只需要分析那些内存占用较大的堆栈,基本不用关心那些内存占用较小的堆栈。所以我们的优化思路也很明确:只保留内存占用较大的堆栈。要完成这个工作就必须对内存中所有堆栈先进行聚类合并,统计出每个堆栈累计的内存值。
具体的优化策略如图 4 所示,对于每个记录到的分配堆栈,首先通过 md5 算法将堆栈数据压缩为 16 字节的 md5,通过 md5 值进行聚类,缓存中只保留 16 字节的 md5 数据,只有当某个堆栈的累计内存超过一定阀值时,才会保留原始堆栈信息,这样因为超过阀值的堆栈数量有限,堆栈原始信息占用的空间几乎就可以忽略不计了。
图 4 堆栈聚类和压缩原理
采用两种方式可以将堆栈降低到优化前的 1/40 左右,优化后的组件内存基本不会对 App 的内存造成太大影响。
数据 Dump 方案
前面提到,在内存触顶后要将内存中的堆栈数据定时 Dump 到磁盘中,常规的方案是 IO 接口直接把数据写入到磁盘。因为数据 Dump 的频率较高,频繁的 IO 操作会导致程序卡顿。因为数据 Dump 的操作是非常高频的,所以我们采用了效率更高的 mmap 方式。
mmap 是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间。实现这样的直接映射关系后,写文件的过程进程不会有额外的文件的数据拷贝操作,避免了内核空间和用户空间的频繁切换,如图 5 所示。根据我们的代码实测,向 mmap 映射空间写数据的性能与直接写内存一致,效率远高于 IO 操作。
图 5 内存映射原理
那么 mmap 的回写时机是怎样的?根据官方文档描述,主要有如下时机:
系统内存不足时
进程 crash 时
主动调用 msync 时
mmap 在内存不足时会主动进行回写操作,这样的机制也保证我们的监控组件能在程序爆内存前将缓存中的数据回写到磁盘,从这一点看采用 mmap 的方式相比常规 IO 操作也有更强可靠性。
内存泄漏检测
除了爆内存堆栈监控,OOMDetector 还集成了内存泄漏检测功能,能够检测 Malloc 内存块和 OC 对象的“无主内存泄漏”。所谓“无主内存泄漏”是指内存块在进程内已经没有引用却无法正常释放的内存块。
按照之前介绍的方案,OOMDetector 可以记录到每一个对象的分配堆栈信息,要从这些对象中找出 “泄漏对象”,我们需要知道在程序可访问的进程内存空间中,是否有“指针变量”指向对应的内存块,那些在整个进程内存空间都没有指针指向的内存块,就是我们要找的泄漏内存块。如图 2 所示,在 IOS 系统中,可能包含指针变量的内存区域有堆内存、栈内存、全局数据区和寄存器,OOMDetector 通过对这些区域遍历扫描即可找到所有可能的“指针变量”,整个扫描流程结束后都没有“指针变量”指向的内存块即是泄漏内存块。
为了避免内存访问冲突,扫描过程需要挂起所有线程,整个过程会卡住程序 1-2 秒。因为扫描过程较为耗时,这个功能目前主要用于 App 的测试阶段,与自动化测试结合可快速高效的发现泄漏问题。
图 6 内存泄漏检测原理
开源只是开始,我们后续仍会不断对 OOMDetector 组件进行改进,也欢迎大家对组件多提意见。如果你的 IOS 应用也在受到内存问题困扰或者你也对 IOS 内存监控技术感兴趣,那么来了解下我们的组件吧!
目前尚无回复
& · & 1785 人在线 & 最高记录 3541 & · &
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.1 · 18ms · UTC 09:02 · PVG 17:02 · LAX 02:02 · JFK 05:02? Do have faith in what you're doing.http://www.cnblogs.com/pengxl/archive//1920947.html
& 需要手动维护的对象是Foundation提供类的对象和用户自定义类的对象。其实就是NSObject的子类。
NSInteger和CGFloat不需要手动回收,因为他们只是用defined定义的某基本类型的别名。
& 需要回收和对象引用计数值会大于零。当引用计数值减于零时,会除释放。
& 对象执行autorelease方法,可以将该对象加入当前所在回收池(NSAutoreleasePool)中。
& 自动释放池(NSAutoreleasePool)对象执行drain操作时,会将加入该池里自动回收的对象引用计数减掉该对象在这个池里执行autorelease的次数。
& 可以将一个对象加到多个自动释放池中。
& 对象执行一次release方法,就会将引用计数减1。
& 只有用[[Class alloc] initXXX]方式声明的对象才需要用[object release]方法释放一次。
& 在我们自定义Class时也应该满足上一条件。
& 我们自定义Class时,对于需要维护类型的对象属性,在@property定义属性时,应加上copy或retain参数。
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!

我要回帖

更多关于 内存检测工具 64位 的文章

 

随机推荐