当前位置: 首页 > news >正文

微型购物网站建设模板网站制作软件平台

微型购物网站建设模板,网站制作软件平台,开发公司质量保证体系,做a免费视频在线观看网站2019独角兽企业重金招聘Python工程师标准 iOS 内存泄露监测 144 作者 谢谢生活 已关注 2017.05.19 17:38* 字数 4235 阅读 209评论 0喜欢 6 iOS可能存在的内存泄露#xff1a;block 循环引用。当一个对象有一个block属性#xff0c;而block属性又引用这个对象… 2019独角兽企业重金招聘Python工程师标准 iOS 内存泄露监测 144 作者 谢谢生活 已关注 2017.05.19 17:38* 字数 4235 阅读 209评论 0喜欢 6 iOS可能存在的内存泄露block 循环引用。当一个对象有一个block属性而block属性又引用这个对象本身那么要造成循环引用。这个时候就用___weak声明下对象用对象的弱引用指针。 头文件相互包含。那么先在.h文件用前向引用声明class(类名);然后在.m文件导入#import AHMessageCell类头文件 移除通知 [[NSNotificationCenter defaultCenter]removeObserver:self];、 移除NSTimer[_timer invalidate];_timer nil; 移除观察者 //添加观察者[self addObserver:#(nonnull NSObject *)# forKeyPath:#(nonnull NSString *)# options:#(NSKeyValueObservingOptions)# context:#(nullable void *)#] //移除观察者[self removeObserver:#(nonnull NSObject *)# forKeyPath:#(nonnull NSString *)#]; timer观察者通知的移除。一般的开发者都是放到dealloc中但是这样不能保证一定能够移除成功。可以更加实际情况移除可以在viewWillAppear中添加viewWillDisappear中移除也可以强制移除。iOS内存泄露测试可以用xcode自带instrument工具,如leaks、Analyze、allocation也可以用第三方工具。一 leaks打开Xcode7自带的Instruments 打开Instruments 按上面操作build成功后跳出Instruments工具选择Leaks选项选择之后界面如下图:打开leaks 到这里之后,我们前期的准备工作做完啦下面开始正式的测试!1.选中Xcode先把程序command R运行起来2.再选中Xcode按快捷键command control i运行起来,此时Leaks已经跑起来了3.由于Leaks是动态监测所以我们需要手动操作APP,一边操作一边观察Leaks的变化当出现红色叉时就监测到了内存泄露点击右上角的第二个进行暂停检测(也可继续检测当多个时暂停一次处理了多个).如图所示:4.下面就是定位修改了,此时选中有红色柱子的Leaks下面有个田字方格点开选中Call Tree显示如下图界面找到内存泄露位置 5.下面就是最关键的一步在这个界面的右下角有若干选框选中Invert Call Tree 和Hide System Libraries,红圈范围内显示如下监测回调函数 到这里就算基本完成啦这里显示的就是内存泄露代码部分那么现在还差一步定位!6.选中显示的若干条中的一条双击会自动跳到内存泄露代码处如图所示 查看回调函数 7.找到了内存泄露的地方那么我们就可以修改即可。二Analyze—静态分析顾名思义静态分析不需要运行程序就能检查到存在内存泄露的地方。使用方法打开Xcodecommand shift B或者Xcode - Product - Analyze 常见的三种泄露情形 1创建了一个对象但是并没有使用。Xcode提示信息 Value Stored to number is never read 。翻译一下存储在number里的值从未被读取过。 2创建了一个指针可变的对象且初始化了但是初始化的值一直没读取过。Xcode提示信息 Value Stored to str during its initialization is never read 3调用了让某个对象引用计数加1的函数但没有调用相应让其引用计数减1的函数。Xcode提示信息 Potential leak of an object stored into subImageRef 。 翻译一下subImageRef对象的内存单元有潜在的泄露风险。 贴上Demo代码 /*** 情 形 一创建了一个对象但是并没有使用。* 提示信息Value Stored to number is never read* 翻译一下存储在number里的值从未被读取过*/ - (void)leakOne {NSString *str1 [NSString string];NSNumber *number;number (str1.length);/*说我们没有读取过它那就读取一下比如打开下面这句代码对它发送class消息就不再会有这个提示了。当然最好的方法还是将有关number的代码都删掉因为你只对number赋值又不使用那干嘛创建出来呢。这是一个比较常见和典型的错误也很容易检查出来*/// [number class]; }/*** 情 形 二创建了一个指针可变的对象且初始化了但是初始化的值一直没读取过。* 提示信息Value Stored to str during its initialization is never read*/ - (void)leakTwo {NSString *str [NSString string]; // 创建并初始化str此时已经有一个内存单元保存str初始化的值// NSString *str; // 这样就内存不泄露因为str是可变的只需要先声明就行。// printf(str前 %p\n,str);str ceshi; // str被改变了指向了ceshi所在的地址指针改变了但之前保存初始化值的内存空间还未释放保存str初始化值的内存单元泄露了。// printf(str后 %p\n,str); // 指针改变了[str class];// 再举两个例子同理NSArray *arr [NSArray array];// printf(arr前 %p\n,arr);// NSArray *arr; // 这样就内存不泄露arr [1,2];// printf(arr后 %p\n,arr); // 指针改变了[arr class];CGRect rect self.view.frame;// CGRect rect CGRectZero; // 这样就内存不泄露rect CGRectMake(0, 0, 0, 0);NSLog(rect %,NSStringFromCGRect(rect)); }/*** 情 形 三调用了让某个对象引用计数加1的函数但没有调用相应让其引用计数减1的函数。* 提示信息Potential leak of an object stored into subImageRef* 翻译一下subImageRef对象的内存单元有潜在的泄露风险*/ - (void)leakThree {CGRect rect CGRectMake(0, 0, 50, 50);UIImage *image;CGImageRef subImageRef CGImageCreateWithImageInRect(image.CGImage, rect); // subImageRef 引用计数 1;UIImage* smallImage [UIImage imageWithCGImage:subImageRef];// 应该调用对应的函数让subImageRef的引用计数减1,就不会泄露了// CGImageRelease(subImageRef);[smallImage class];UIGraphicsEndImageContext(); } 监测结果可能存在内存泄露的地方 三allocation使用这个时候我们通过Allocation可以进行内存分析将Xcode切换为Release状态通过Product→ProfileCmdi找到Allocations: 代开allocation 1.红色的按钮是表示停止和启动应用程序不要理解成了暂停,Objective-C所有的对象都是在堆上分配的记得勾选一下All Heap Allocations: 开始监测 2.点击All Heap Allocation勾选Call Tree同时不查看系统的函数库: 监测回调函数 3.具体方法占用的内存可以逐级点开效果如下: 内存占用 以上是常规的Allocations使用关于第二张图的有框中的几个选项可以解释一下: Separate by Thread: 每个线程应该分开考虑考虑到应用程序中GCD的存在 Invert Call Tree: 从上倒下跟踪堆栈,这意味着你看到的表中的方法,将已从第0帧开始取样,利用栈的先进后出的特性我们可以在栈顶看到最近调用的函数 Hide System Libraries: 勾选此项会显示app的代码,这是非常有用的 Flatten Recursion: 递归函数, 每个堆栈跟踪一个条目左侧有几个比较有用的选项 All Objects Created Created Still Living Created Destroyed 内存监测 4.Allocation 分析技巧 通过以上方法可以对应用的整体内存使用情况有所了解但内存不合理使用导致的内存警告往往是部分代码或视图导致的我们往往要关注于某段时间或操作过程中内存的分配和使用情况Allocation提供了这种功能。 比如在进入一个视图前或操作前我们在Allocation面板左侧点击Mark Generation这时候会产生Generation A节点显示内存当前的情况 比较测出内存泄露点 我们可以在进入视图后再点一次Mark Generation在视图退出后再点一次Mark这样三次产生的 Generation分别记录了进入前、进入后、关闭后再最后一个Generation应该内存被合理释放否则就代表了在这个视图或操作中有泄漏或不合理的地方。 以上只是Allocation的基本运用设计出一套使用Allocation来合理测试的方案是比较复杂的后续慢慢介绍。四MLeaksFinderMLeaksFinder 提供了内存泄露检测更好的解决方案。只需要引入 MLeaksFinder就可以自动在 App 运行过程检测到内存泄露的对象并立即提醒无需打开额外的工具也无需为了检测内存泄露而一个个场景去重复地操作。MLeaksFinder 目前能自动检测 UIViewController 和 UIView 对象的内存泄露而且也可以扩展以检测其它类型的对象。 MLeaksFinder 的使用很简单参照 https://github.com/Zepo/MLeaksFinder基本上就是把 MLeaksFinder 目录下的文件添加到你的项目中就可以在运行时debug 模式下帮助你检测项目里的内存泄露了无需修改任何业务逻辑代码而且只在 debug 下开启完全不影响你的 release 包。 当发生内存泄露时MLeaksFinder 会中断言并准确的告诉你哪个对象泄露了。这里设计为中断言而不是打日志让程序继续跑是因为很多人不会去看日志断言则能强制开发者注意到并去修改而不是犯拖延症。 中断言时控制台会有如下提示View-ViewController stack 从上往下看该 stack 告诉你MyTableViewController 的 UITableView 的 subview UITableViewWrapperView 的 subview MyTableViewCell 没被释放。而且这里我们可以肯定的是 MyTableViewControllerUITableViewUITableViewWrapperView 这三个已经成功释放了。 * Terminating app due to uncaught exception NSInternalInconsistencyException, reason: Possibly Memory Leak.In case that MyTableViewCell should not be dealloced, override -willDealloc in MyTableViewCell by returning NO.View-ViewController stack: ( MyTableViewController, UITableView, UITableViewWrapperView, MyTableViewCell)从 MLeaksFinder 的使用方法可以看出MLeaksFinder 具备以下优点 使用简单不侵入业务逻辑代码不用打开 Instrument 不需要额外的操作你只需开发你的业务逻辑在你运行调试时就能帮你检测 内存泄露发现及时更改完代码后一运行即能发现这点很重要你马上就能意识到哪里写错了 精准能准确地告诉你哪个对象没被释放原理(http://wereadteam.github.io/2016/02/22/MLeaksFinder/?fromsinglemessageisappinstalled0#u539F_u7406) MLeaksFinder 一开始从 UIViewController 入手。我们知道当一个 UIViewController 被 pop 或 dismiss 后该 UIViewController 包括它的 viewview 的 subviews 等等将很快被释放除非你把它设计成单例或者持有它的强引用但一般很少这样做。于是我们只需在一个 ViewController 被 pop 或 dismiss 一小段时间后看看该 UIViewController它的 viewview 的 subviews 等等是否还存在。 具体的方法是为基类 NSObject 添加一个方法 -willDealloc 方法该方法的作用是先用一个弱指针指向 self并在一小段时间(3秒)后通过这个弱指针调用 -assertNotDealloc而 -assertNotDealloc 主要作用是直接中断言。- (BOOL)willDealloc { __weak id weakSelf self; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [weakSelf assertNotDealloc]; }); return YES;}- (void)assertNotDealloc { NSAssert(NO, “”);} 这样当我们认为某个对象应该要被释放了在释放前调用这个方法如果3秒后它被释放成功weakSelf 就指向 nil不会调用到 -assertNotDealloc 方法也就不会中断言如果它没被释放泄露了-assertNotDealloc 就会被调用中断言。这样当一个 UIViewController 被 pop 或 dismiss 时我们认为它应该要被释放了我们遍历该 UIViewController 上的所有 view依次调 -willDealloc若3秒后没被释放就会中断言。在这里有几个问题需要解决 不入侵开发代码 这里使用了 AOP 技术hook 掉 UIViewController 和 UINavigationController 的 pop 跟 dismiss 方法关于如何 hook请参考 Method Swizzling。遍历相关对象 在实际项目中我们发现有时候一个 UIViewController 被释放了但它的 view 没被释放或者一个 UIView 被释放了但它的某个 subview 没被释放。这种内存泄露的情况很常见因此我们有必要遍历基于 UIViewController 的整棵 View-ViewController 树。我们通过 UIViewController 的 presentedViewController 和 view 属性UIView 的 subviews 属性等递归遍历。对于某些 ViewController如 UINavigationControllerUISplitViewController 等我们还需要遍历 viewControllers 属性。构建堆栈信息 需要构建 View-ViewController stack 信息以告诉开发者是哪个对象没被释放。在递归遍历 View-ViewController 树时子节点的 stack 信息由父节点的 stack 信息加上子结点信息即可。例外机制 对于有些 ViewController在被 pop 或 dismiss 后不会被释放比如单例因此需要提供机制让开发者指定哪个对象不会被释放这里可以通过重载上面的 -willDealloc 方法直接 return NO 即可。特殊情况 对于某些特殊情况释放的时机不大一样比如系统手势返回时在划到一半时 hold 住虽然已被 pop但这时还不会被释放ViewController 要等到完全 disappear 后才释放需要做特殊处理具体的特殊处理视具体情况而定。系统View 某些系统的私有 View不会被释放可能是系统 bug 或者是系统出于某些原因故意这样做的这里就不去深究了因此需要建立白名单手动扩展 MLeaksFinder目前只检测 ViewController 跟 View 对象。为此MLeaksFinder 提供了一个手动扩展的机制你可以从 UIViewController 跟 UIView 出发去检测其它类型的对象的内存泄露。如下所示我们可以检测 UIViewController 底下的 View、Model- (BOOL)willDealloc { if (![super willDealloc]) { return NO; } MLCheck(self.viewModel); return YES;} 这里的原理跟上面的是一样的宏 MLCheck() 做的事就是为传进来的对象建立 View-ViewController stack 信息并对传进来的对象调用 -willDealloc 方法。五faceBook提供的内存泄露自动化测试FBRetainCycleDetector、FBAllocationTracker、FBMemoryProfiler。让这工具真正闪光的是在工程师内部构建的时候它会连续的、自动的运行。 客户端部分自动化是简单的。我们在定时器上运行循环引用检测器定期扫描内存去寻找循环引用虽然这不是完全没有问题。当我们第一次运行分析器的时候我们意识到它不足以很快的扫描整个内存空间。当它开始检测的时候我们需要给它提供一组候选对象。 为了更有效的解决这个问题我们开发了FBAllocationTracker。这个工具会主动跟踪NSObject 子类的创建和释放。它可以以一个很小的性能开销来获取任何类的任何实例。 对于客户端的自动化只要在NSTimer 上使用FBRetainCycleDetector再用FBAllocationTracker来抓取实例来配合跟踪就行。 现在让我们来仔细看看后台会发生什么。 循环引用可以包含任何数量的对象。一个坏的连接会导致很多环的时候这就复杂了。在环中A→B是一个坏连接创建了两个环A-B-C-D 和 A-B-C-E。 这有两个问题 我们不想给一个坏连接导致的两个循环引用分别标记。 我们不想给可能代表两个问题的两个循环引用一起标记即使它们共享一个连接。所以我们需要给循环引用定义簇组(clusters)鉴于这些启发我们写了个算法来找到这些问题。 在给定的时间收集所有的环。 对于每一个环提取Facebook特定的类名。 对于每一个环找到包含在环内的被报告的最小的环。 依据上面的最小环将环添加到组中。 只报告最小环。最后一部分是找出谁第一时间偶然引入了循环引用。我们可以通过环中的”git/hg责任”的部分代码来猜测最近的变化所导致的问题。最后一个接触这个代码的人将会收到修复代码的任务。 整个系统如下:手动性能分析 虽然自动化有助于简化发现循环引用的过程降低人员的消耗手动性能分析依然有它的用武之地。我们创建的另一个工具允许任何人查看内存使用甚至不需要把他的手机插到电脑上。 FBMemoryProfiler可以很容易的添加到任何应用程序可以让你手动配置构建文件可以让你在应用程序内运行循环应用检测。它会借用FBAllocationTracker和FBRetainCycleDetector来实现此功能。生成(Generations) FBMemoryProfiler的一个很伟大的特性是“生成追踪(generation tracking)”类似于苹果的Instruments的生成追踪。生成只是简单的在两次标记之间拍摄所有仍然活着的对象的快照。 使用FBMemoryProfiler的界面,我们可以标记生成例如分配三个对象。然后我们标记另一个生成之后继续分配对象。第一个生成包含我们一开始的三个对象。如果任意一个对象被释放了它会从我们第二个生成中移除。当我们有一个重复的任务我们认为可能会内存泄露的时候生成追踪是很有用的例如导航View Controller的进出。在每次开始我们的任务的时候我们标记一个生成然后对之后的每个生成进行调查。如果一个对象不应该活这么长时间我们可以在FBMemoryProfiler界面清楚地看到。 Check Out 无论你的应用程序是大是小功能是多是少好的工程师都应有好的内存管理。在这些工具的帮助之下我们可以更简单的找到并修复这些内存泄露所以我们可以花费更少的时间去手动处理这样就可以有更多的时间去编写更好的代码。我们也希望你可以发现它们是有用的。在Github上check out下来吧。FBRetainCycleDetector, FBAllocationTracker 和 FBMemoryProfiler。   转载于:https://my.oschina.net/u/2562364/blog/906566
http://www.pierceye.com/news/172002/

相关文章:

  • 制作网站教学设计金湖县城乡建设局网站
  • 微商城网站建设咨询网站做的不满意
  • 装企工长网站开发互联网营销师考试内容
  • 广州高端网站定制公司哪家好全椒县城乡规划建设局网站
  • 物流网站毕业设计论文论坛网站模板下载
  • 代理上网蜗牛精灵seo
  • 网站怎么做用qq登录接入网络舆情监测分析系统
  • 怎么把几个网站做互通wordpress 英文站
  • 建设高端网站需要多少钱wordpress检测
  • 如何学习网站建设app嘉兴建站软件
  • 驻马店市建设工程网站平面设计培训班学费一般多少百度贴吧
  • 长沙网络建设的网站免费的个人简历模板word下载
  • 网站维护简单吗wordpress绿色两栏响应式主题
  • 二手站网站怎做福州网站建设的公司哪家好
  • dw如何做网站后台佛山行业网站建设
  • 如何做网站轮播大图简单网页制作成品代码
  • 网站怎么做uc整合查企业网站
  • 网站没被收录什么原因网站排名点击工具
  • 江西南昌建设厅网站商品展示软件
  • 眼镜企业网站建设方案2015做那些网站致富
  • 创建个人网站的流程建设网站聊天室
  • cms 学校网站上海模板网站
  • 网站建设投资风险分析公司做的网站费用如何做账
  • 网站建设费用核算科目DW做的网页用网站打不开
  • wordpress标签搜索引擎嘉兴市做网站优化
  • 网站更换关键词怎么做好wordpress post fonts
  • 厦门优化网站排名网站备案转服务器
  • 怎样做pdf电子书下载网站做旅行攻略的网站
  • 怎样做网站推广啊抖音网站的flash怎么做
  • 网站建设小说网站建设目标是什么意思