• 05-【性能优化】之分配工具


    分配,分配,分配
    接下来的仪器是分配工具。它能给出你所有创建和存储它们的内存的详细信息,它也显示你保留了每个对象的计数。
     
    关闭仪器,回到Xcode和选择Product->Profile。然后,从选择器分配并单击配置文件。如下图:
     
    程序再次打开 然后你会看到
     
    这个时候你会发现两个曲目。一个叫(分配)Allocations,以及一个被称为VM Tracker(虚拟机跟踪)。该分配轨道将详细在本教程中讨论;虚拟机跟踪也是非常有用的,但更复杂一点。
     
    所以你的错误会追踪下?
     
    有隐藏的项目,你可能不知道有东西在那儿。你可能已经听说了内存泄漏。但你可能不知道的是,其实有两种泄漏。
     
    第一个是真正的内存泄漏,一个对象尚未被释放,但是不再被引用的了。因此,存储器不能被重新使用。
     
    第二类泄漏是比较麻烦一些。这就是所谓的“无界内存增长”。这发生在内存继续分配,并永远不会有机会被释放。
     
    如果永远这样下去你的程序占用的内存会无限大,当超过一定内存的话 会被系统的看门狗给kill掉.
     
    建立一个场景,你可以检测出无限的内存增长。首先,在应用程序使10个不同的搜索(不要用已经存在的搜索)。确保搜索的一些结果!现在让程序等待几秒钟。
     
    你应该已经注意到,在分配的轨道图不断上升。这是告诉你的,内存被分配了。它的这一特征,将引导你找到无限的内存增长。
     
    你将要执行的是“heap shot analysis”。为此,按这个按钮叫“Mark Heap”。你会发现的详细面板左侧的按钮
    按下它,你会看到一个红色的标志出现在轨道上,像这样:
     
    heap shot分析的目的是执行一个动作多次,看看如果内存是否无限增长。搜索一个内容,稍等几秒加载图像,然后返回主页。然后再标记堆。反复这样做不同的搜索。
    演戏几个搜索后,仪器会看起来像这样:
    这时你应该会疑问。图中的蓝色是怎么回事了,你继续这样操作10次这样的搜索 蓝色还不断变高:
     
    那肯定是不好的。别急,有什么关于内存的警告?你知道这些,对不对?内存警告是告诉一个应用程序,内存警告是ios处理app最好的方式尤其是在内存越来越吃紧的时候,你需要清除一些内存。
     
    内存一直增长其实也不一定是你的代码除了问题,也有可能是UIKit 系统框架本身导致的.
     
    通过选择HardwareSimulate内存警告在iOS模拟器的菜单栏模拟内存警告。你会发现,记忆体使用量出现小幅回落,但绝对不会回到它应该的。所以还是有无限的内存增长发生的地方。
     
    究其原因,堆出手做钻进搜索的每次迭代后,你可以看到内存的分配每个镜头之间。一起来看看在详细信息面板,你会看到一堆一堆的镜头。
     
    在iOS模拟器的菜单栏中选择hardwaresimulate内存警告模拟内存警告。你会发现内存使用会出现小幅回落,但肯定不会回到它应该在的地方。
     
    每一次的搜索后做你可以看到内存已拍摄之间的分配。在详细信息面板看一看,你会看到一好多堆镜头。
     
    稳准狠
    第一个堆镜头作为参照,然后随便打开一个堆镜头,你会看到如下:
     
    靠,这是一个很大的对象!从哪里开始看呢?
     
    最好的方式是通过列表,你在你的应用程序直接使用的类。在这种情况下,HTTPHeaderDict,CGRegion,CGPath,CFNumber,等等都是可以忽略了。
     
    但是,一个突出的是UIImage,这肯定是在你程序使用的。点击上的UIImage左侧的箭头显示的完整列表。选择一个,在扩展详细信息面板:
    图中灰色的是系统库,黑色部分是你应用的代码,要获得此跟踪更多的上下文,双击唯一的黑框ImageCache方法,这时候将掉转到如下方法
     
    1. - (void)downloadImageAtURL:(NSURL*)url completionHandler:(ImageCacheDownloadCompletionHandler)completion { 
    2.     UIImage *cachedImage = [self imageForKey:[url absoluteString]]; 
    3.     if (cachedImage) { 
    4.         completion(cachedImage); 
    5.     } else { 
    6.         dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    7.             NSData *data = [NSData dataWithContentsOfURL:url]; 
    8.             UIImage *image = [UIImage imageWithData:data]; 
    9.             [self setImage:image forKey:[url absoluteString]]; 
    10.             dispatch_async(dispatch_get_main_queue(), ^{ 
    11.                 completion(image); 
    12.             }); 
    13.         }); 
    14.     } 
     
    工具是非常有用的,你现在要努力通过自己的代码思考发生了什么.看看通过上面的方法,你会看到它调用一个名为setImage方法:forKey:。这种方法在缓存以防它再次使用以后的应用程序的图像。啊!那么这肯定听起来像它可能是一个问题!
     
    一起来看看该方法的实现:
     
    1. - (void)setImage:(UIImage*)image forKey:(NSString*)key { 
    2.     [_cache setObject:image forKey:key]; 
     
    从网络上下载一个图片添加字典中,你会注意到这些图片从来没有从字典清楚过。
     
    ,这就是内存为什么会一直增长,因为应用程序并不会从缓存里删除东西.它只会一直增加他们。
     
    要解决此问题,你需要的是ImageCache收到UIApplication内存吃紧的警告时.清理缓存。
     
    为了使ImageCache能接收通知,修改init方法如下:
     
    1. - (id)init { 
    2.     if ((self = [super init])) { 
    3.         _cache = [NSMutableDictionary new]; 
    4.         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(memoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; 
    5.     } 
    6.     return self; 
     
    注册UIApplicationDidReceiveMemoryWarningNotification执行memoryWarning:方法。
    1. - (void)memoryWarning:(NSNotification*)note { 
    2.     [_cache removeAllObjects]; 
    memoryWarning删除缓存中的所有对象。这将确保没有持图像。
     
    为了测试此修复程序,再次启动仪器(从Xcode中有cmd)和重复的步骤。不要忘了在模拟结束内存警告!
     
    注意:请确保您从Xcode中退出,重新构建,而不是仅仅点击仪器仪表上的红色按钮,以确保您使用的是最新的代码。
     
    这一次分析应该是这样的:
     
    这个时候,内存受到内存警告后急剧下降。但还是有一些内存整体增长,但远不及像以前那样。
     
    究其原因还是有一定的增长确实是由于系统库,并没有太多可以做的。看来,系统库不释放所有的内存,这可能是由设计或可能是一个错误。你可以在你的应用程序做的是释放尽可能多的内存越好,你已经做到这一点!
     
    干得好!还有一个问题,修补了, - 仍然有泄漏,你还没有解决的第一种类型的问题。
  • 相关阅读:
    [编写高质量代码:改善java程序的151个建议]建议72 生成字列表后不要再操作原列表
    [编写高质量代码:改善java程序的151个建议]建议71 推荐使用subList处理局部列表
    [编写高质量代码:改善java程序的151个建议]建议70 子列表只是原列表的一个视图
    程序员的简历到底该怎么写?(转)
    SQL数据库数据优化SQL优化总结( 百万级数据库优化方案)
    sqlserver的四种分页方式
    sql server中截取字符串的常用函数(自己经常到用的时候想不起来所以拿到这里)
    SQL之存储过程详细介绍及语法(篇幅比较长慢慢看)
    超经典SQL练习题,做完这些你的SQL就过关了
    SqlServer 数据库引擎优化顾问优化数据库(消耗内存很大)
  • 原文地址:https://www.cnblogs.com/iyuanxiaojun/p/4468990.html
Copyright © 2020-2023  润新知