zoukankan      html  css  js  c++  java
  • 用Instruments检测内存泄露

    标签:Xcode
    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://dawn110110.blog.51cto.com/3049492/899283
    IPhone上木有垃圾回收,动态申请的内存要自己记得释放,此文自己总结一下可能出现内存泄露的各种情况,以及检测方法。
     
    内存泄露说白了,就是有这样一块动态申请的内存,但木有任何一个指针指向它。
     
    举例来说,在C++中:
     
    1. MyClass * foo = new MyClass;  
    2. foo = NULL; 
     
    类似地在objective-C中:
     
    1. MyClass *foo = [[MyClass alloc] init];  
    2. foo = nil;//内存泄露了! 
     
     
    或者有这样一个类:
     
    1. @interface Foo : NSObject  
    2. {}  
    3. @end  
    4.  
    5. @implementation Foo  
    6. -(id) init  
    7. {  
    8.         if ((self = [super init])) {  
    9.                 NSMutableString * string = [[NSMutableString alloc] initWithString:@"Leaker!!!"];  
    10.                 string = nil;//泄露了!这句之后那个字符串对象应用退出之前不会被释放。 
    11.         }  
    12.         return self;  
    13. }  
    14. - (void) dealloc  
    15. {  
    16.         [super dealloc];  
    17. }  
    18. @end 
     
    出现内存泄露会怎样?
    答:很小的泄露,没事!应用退出的时候所用内存都会被清理,包括泄露的,而且IPhone应用不会申请到共享内存,不会波及到整个系统,不会出现系统范围的内存泄露。要是泄露的比较多,而且反复不停地出现内存泄露,顶多应用崩溃掉。不过想发布到AppStore的话,有内存泄露一般会被苹果拒绝……。
     
    先来看看IPhone里内存是怎么管理的,首先:木有自动垃圾回收!其次:有引用记数!
    NSObject对象有个属性:retainCount,所以所有对象都要继承自NSObject,才有统一的引用计数…。
     
    然后牢记记住下面8件事:
    • 1 这个retainCount == 0的时候,对象的dealloc方法会被调用,对象就被释放了。
    • 2 永远不要显示调用dealloc方法
    • 3 [obj retain]; // obj.retainCount++ 引用记数+1
    • 4  [obj release]; // obj.retainCount-- 引用记数-1
    • 5 MyClass * obj = [[MyClass alloc] init];// obj.retainCount = 1 初值为1
    • 6 对于有retain特性的属性比如下面这个:
      1. @interface MyClass : NSObject {  
      2.   NSObject* foo;  
      3. }  
      4. @property (noatomic,retain) NSObject * foo;  
      5. @end  
      6.  
      7. @implementation MyClass  
      8. @synthesize foo;  
      9. ...  
      10.   //下面两行正确的写法  
      11.   self.foo = bar;// [foo release]; foo = bar; [foo retain]; 会发一个release给原来的对象,发一个retain 给新对象  
      12.   self.foo = nil;// [foo release]; 会发一个release 消息给对象  
      13.  
      14.   //下面一行写法不对  
      15.   foo = bar;// 没发release给foo 没发retain给bar ,这种写法是不对的。  
      16. ...  
      17. @end 
      参考: 
     
    • 7 对于stringWithString 这种方法创造的对象,一个Runloop结束时,对象会被发送一个release消息,需要注意的有两点,一是注意理解Runloop,避免Runloop结束后对象被释放了却又使用对象,二是 如果用instruments工具检测内存泄露,这种使用autorelease的情况也会被当做内存泄露处理,注意识别……。
    • 8 对于NSMutableArray这种类,当addObject的时候,相应被加入array中的那个对象的引用计数会被+1,当array本身释放时,它会先给array中的所有对象发一个release消息。
     
    可以用Instruments检测内存泄露,里各种各样的工具,用Leaks。
    用起来很简单:用Xcode(4.3)打开相应的项目,Product->Profile,选Leaks工具。 之后会动态地记录应用运行过程中,有哪些地方出现内存泄露。 需要注意的地方有二:
    1 对于被autorelease的对象,Leak工具也会视其为泄露,自己知道没问题就行。
    2 记得点开Extended Detail ,对于每一出泄露,可以在这里看到调用堆栈,双击调用堆栈中的某一项,可以直接定位到代码,便于查错跟修改。 情况如下两个图:
     
     
    Leak
     
    代码定位

    本文出自 “我已成妖” 博客,请务必保留此出处http://dawn110110.blog.51cto.com/3049492/899283

  • 相关阅读:
    【BZOJ 4151 The Cave】
    【POJ 3080 Blue Jeans】
    【ZBH选讲·树变环】
    【ZBH选讲·拍照】
    【ZBH选讲·模数和】
    【CF Edu 28 C. Four Segments】
    【CF Edu 28 A. Curriculum Vitae】
    【CF Edu 28 B. Math Show】
    【CF Round 439 E. The Untended Antiquity】
    【CF Round 439 C. The Intriguing Obsession】
  • 原文地址:https://www.cnblogs.com/DamonTang/p/2648699.html
Copyright © 2011-2022 走看看