内存分析

内存分析

主要目的就是为了检测程序是否存在内存泄露

1. 静态内存分析(Analyze)

作用(可检出下述错误):
    > 逻辑错误:访问未初始化的变量, 野指针等;
    > 声明错误:从未使用过的对象;
    > 内存管理错误:如内存泄漏等;
分析方法:
    > 静态内存分析是不运行程序,直接对代码进行分析.
    > 根据代码的上下文的语法结构,来分析是否有内存泄露
缺点:
    > 不一定准确,但是如果发现有提示,那么去结合上下文看一下,这里的代码是否有问题
// 测试不准确的情况
NSObject *obj = [self obj];
NSLog(@"%@", obj);
[obj release];

- (id)obj {
    return [[NSObject alloc] init]; // 提示错误:Potential leak of an object
}

2. 动态内存分析

作用:
    > 检测程序在运行过程中是否存在内存泄露
    > 查看是内存的分配情况
    > 查看内存是否有释放
名词解释:
    Anonymous VM(匿名虚拟内存)是系统为程序预留的、可能会立即被重复使用的一部分可用内存
内存检测工具----Instruments
    1. 使用:xcode---product----Profile----Leak;运行程序,通过使用app,若红色区域代表内存泄漏出现的地方。
    2. 使用:xcode---product----Profile----Allocations;运行程序,通过使用app,可以查看做出了某个操作后(比如点击了某个按钮\显示了某个控制器), 内存是否有暴增的情况(突然变化)

3. Foundation 和 CoreFoundation框架的内存管理

MRC--ARC环境的切换方式:target -> build setting -> 搜索 automatic reference counting

> MRC 下桥接 - Foundation 和 CoreFoundation框架的数据类型转换:
    1. 都是强制数据类型转换,不会移交对象内存管理所有权
    // > MRC 下桥接
    // 直接转换
    // 1.  Foundation -> CoreFoundation:
    NSString *str = [[NSString alloc] initWithCString:"123" encoding:NSUTF8StringEncoding];
    // 这种转换, 不会移交对象的内存管理权
    CFStringRef strRef =(CFStringRef)str;
    NSLog(@"%@", strRef);
    [str release];
    //     CFRelease(strRef);

    // 2.  CoreFoundation -> Foundation:
    CFStringRef strRef2 = CFStringCreateWithCString(CFAllocatorGetDefault(), "123", kCFStringEncodingUTF8);
    // 这种转换, 不会移交对象的内存管理权
    NSString *str2 = (NSString *)strRef2;
    NSLog(@"%@", str2);
    CFRelease(strRef2);
    ```

---
    > ARC 下桥接 - Foundation 和 CoreFoundation框架的数据类型转换:
        1.  Foundation -> CoreFoundation:
            1. __bridge方式 :不会移交对象内存管理所有权
            2. CFBridgingRetain = __bridge_retained方式:会移交对象内存管理所有权
        2.  CoreFoundation -> Foundation:
            1. __bridge方式 :不会移交对象内存管理所有权
            2. CFBridgingRelease = __bridge_transfer方式:会移交对象内存管理所有权

```objc
// > ARC 下桥接
    // 1.  Foundation -> CoreFoundation:
     NSString *str = [[NSString alloc] initWithCString:"123" encoding:NSUTF8StringEncoding];

    // 转换方式1: __bridge CFStringRef 这种转换, 不会移交对象的内存管理权, 类似于, 直接转换
//    CFStringRef strRef = (__bridge CFStringRef)(str);

    // 转换方式2: CFBridgingRetain == __bridge_retained CFStringRef , 这种方式转换, 会移交对象的内存管理权
     CFStringRef strRef = (__bridge_retained CFStringRef)(str);
     NSLog(@"%@", strRef);

    CFRelease(strRef);

    // 2.  CoreFoundation -> Foundation:
    CFStringRef strRef2 = CFStringCreateWithCString(CFAllocatorGetDefault(), "123", kCFStringEncodingUTF8);

    // 转换方式1: (__bridge NSString *)  直接转换, 不会移交对象的内存管理权
//    NSString *str2 = (__bridge NSString *)(strRef2);

    // 转换方式2: CFBridgingRelease == __bridge_transfer NSString * 会移交对象的内存管理权
     NSString *str2 = (__bridge_transfer NSString *)(strRef2);
    NSLog(@"%@", str2);

4. 内存分析工具

5. OC内存使用总结

1. 如何让程序尽量减少内存泄漏
    1.非ARC
        1. Foundation对象(OC对象) : 只要方法中包含了alloc\new\copy\mutableCopy\retain等关键字, 那么这些方法产生的对象,就必须在不再使用的时候调用1次release或者1次autorelease
        2. CoreFoundation对象(C对象) : 只要函数中包含了create\new\copy\retain等关键字,那么这些方法产生的对象, 就必须在不再使用的时候调用1次CFRelease或者其他release函数
    2. ARC
        只自动管理OC对象, 不会自动管理C语言对象
        * CoreFoundation对象(C对象) : 与非ARC一致

6. swift的内存管理

  • 通过arc管理内存
  • 关于Swift中使用CoreFoundation数据类型,使用了"类型重映射"机制, 转换成为了能够自动管理内存的对象,不需要我们手动释放

7. 图片加载的内存分配

> imageNamed:图片会在内存中有缓存, 而且不会被释放
> 基本上,除此之外的图片加载方法:图片没有缓存,可以被释放

补充:
    1. 图片在沙盒中的存在形式
        1.如果项目的Deployment Target <= 6.x (不支持图片压缩);
            1> 所有图片直接暴露在沙盒的资源包(main Bundle), 不会压缩到Assets.car文件
        2.如果项目的Deployment Target >= 7.x (支持图片压缩)
            1> 放在Images.xcassets里面的所有图片会压缩到Assets.car文件, 不会直接暴露在沙盒的资源包(main Bundle)
            2> 没有放在Images.xcassets里面的所有图片会直接暴露在沙盒的资源包(mainBundle),不会压缩到Assets.car内
    2. 图片加载方法
        放在Images.xcassets里面的所有图片 : 无法得到图片的全路径,只能通过图片名(imageNamed:方法)来加载图片
        没有放在Images.xcassets里面的所有图片:可以获取全路径,可以使用所有方法加载
    3.结论:
        小图片\使用频率比较高的图片;放在Images.xcassets里面
        大图片\使用频率比较低的图片(一次性的图片, 比如版本新特性的图片);不要放在Images.xcassets里面
    4. 怎样解压.car压缩包, 获取资源:https://github.com/devcxm/iOS-Images-Extractor

8. 内存/性能优化

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容