内存管理(1)
来源:互联网 发布:mac cue 分割 wav 编辑:程序博客网 时间:2024/05/17 09:30
1.【掌握】内存管理的基本概念及范围
1、内存管理的基本概念
1、为什么要进行内存管理?
- 不难发现,苹果手机与安卓手机比较起来,苹果手机尤为流畅,性能相比起来会好很多,这个与苹果手机内存管理是分不开的。
在程序开发中,应该及时将不用的数据回收,合理分配和管理内存 ,以提高程序的运行效率。
2、哪些行为会增加内存占用?
- 创建1个OC对象
- 定义1个变量
调用1个函数或者方法
- 分析下图有哪些对象?
- 由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当APP使用的内存超过20M,系统会向该APP发送内存警告消息,收到此消息后,需要回收一些不需要再继续使用的内存空间,比如回收一些不再使用的对象和变量等,否则程序会崩溃。
- 分析下图有哪些对象?
2、OC内存管理的范围
- 管理范围:
管理任何继承NSObject的对象,对其他的基本数据类型无效。
- 本质原因:是因为对象和其他数据类型在系统中的存储空间不一样,其他局部变量主要存放于栈中,而对象存储于堆中。当代码块结束时,这个代码块中涉及的所有局部变量会被回收,指向对象的指针也被回收,此时,对象已经没有指针指向,但依然存在于内存中,造成内存泄露。
2.【理解】内管管理的原理及分类
1、内存管理的原理
理解内存管理的原理,要清楚两个概念:
- 1)对象的所有权
- 2)引用计数器
- 1)对象的所有权
- 任何对象都可能拥有一个或多个所有者。只要一个对象至少还拥有一个所有者,它就会继续存在。
- 那么什么叫拥有者呢? 举一个例子来看:
- 假设有一个办公室, 给大家办公,那么如果办公室里没有人, 也就是说没有人在使用这个办公室, 就可以将办公室的灯关掉。 如果有人, 才会开灯。如果只有一个人在,那么当这个人离开的时候, 就表示需要将等关掉。
那么此时就说明这个人是这间办公室的所有者.
- 同时, 一个对象允许有多个所有者, 就好比:
- 劲舞团
这里有很多人,如果其中某个人退出,此房间是不会被回收的,因为还有其他人在使用该房间。
LOL组队
- Cocoa所有权策略
任何自己创建的对象都归自己所有,可以使用名字以“alloc”或“new”开头或名字中包含“copy”的方法创建对象,可以使用retain来获得一个对象的所有权。
- 2)对象的引用计数器
- 每个OC对象都有自己的引用计数器,是一个整数表示对象被引用的次数(有多少个所有者),即现在有多少东西在使用这个对象。对象刚被创建时,默认计数器值为1,当计数器的值变为0时,则对象销毁。
- 对象的结构:
- 在每个OC对象内部,都专门有8个字节的存储空间来存储引用计数器。
* 3)引用计数器的作用
* 引用计数器是判断对象要不要回收的依据(存在一种例外:对象值为nil时,引用计数为0,但不回收空间)就是计数器是否为0,若不为0则存在。
* 4)对引用计数器的操作
* 想要管理对象占用的内存,就要学会操作引用计数器。
引用计数器的常见操作
- retain消息:使计数器 +1(该方法返回对象本身)
- release消息:使计数器 -1(不代表释放对象)
- retainCount:获得对象当前的应用计数器值,输出:%ld %lu
注意:release不代表销毁对象,仅仅是引用计数器-1
5)对象的销毁
- 当1个对象的应用计数器为0时,那么它将被销毁,其占用的内存被系统回收。
- 当对象被销毁时,系统会自动向对象发送一条dealloc消息。一般会重写dealloc方法,在这里释放相关的资源,dealloc就像是对象的“临终遗言”。
- 一旦重写了dealloc方法,就必须调用[super dealloc],并且放在代码块的最后调用。
注意:不能直接调用dealloc方法
。一旦对象被回收了,那么他所占用的存储空间就不再可用,坚持使用会导致程序崩溃(野指针错误)
- 注意;
- 1) 如果对象的计数器不为0,那么在整个程序运行过程,它占用的内存就不可能被回收(除 非整个程序已经退出 )
- 2)任何一个对象,刚生下来的时候,引用计数器都为1。(对象一旦创建好,默认引用计数器就是1)当使用alloc、new或者copy创建一个对象时,对象的引用计数器默认就是1.
2、内存管理的分类
Objective-C提供了三种内存管理方式:
- 1.MannulReference-Counting(MRC,手动管理,在开发iOS4.1之前的版本的项目时我们要自己负责使用引用计数来管理内存,比如要手动 retain、release、autorelease 等,而在其后 的版本可以使用 ARC,让系统自己管理内存。)
- 2.automatic reference-counting(ARC,自动引用计数,iOS4.1之后推出的)
3.garbage collection(垃圾回收)。iOS不支持垃圾回收;
ARC作为苹果新提供的技术,苹果推荐开发者使用ARC技术来管理内存;
开发中如何使用:需要理解MRC,但实际使用时尽量用ARC。
- MRC和ARC的区别:
4.【理解】内存管理的原则
1、内存管理的原则
1.原则
- 只要还有人在使用某个对象,那么这个对象就不会被回收;
- 只要你想使用这个对象,那么就应该让这个对象的引用计数器+1;
- 当你不想使用这个对象时,应该让对象的引用计数器-1;
2.谁创建,谁release
- 1)如果你通过alloc,new,copy来创建了一个对象,那么你就必须调用release或者 autorelease方法.
- 2)不是你创建的就不用你去负责
3.谁retain,谁release
- 只要你调用了retain,无论这个对象时如何生成的,你都要调用release
4.总结
- 有始有终,有加就应该有减。曾经让某个对象计数器加1,就应该让其在最后-1.
2、内存管理研究内容
- 1.野指针(僵尸对象)
- 僵尸对象: 已经被销毁的对象(不能再使用的对象).
- 野指针:指向僵尸对象(不可用内存)的指针.
- 空指针: 没有指向存储空间的指针(里面存的是nil, 也就是0)
- 2.内存泄露
- 如果在程序结束后,对象没有被释放,此时称为内存泄露。
Student *s = [[Student alloc] init]; Student *s1 = [s retain];
- 那么,问题来了,最后由谁释放?
- 1> 由s释放
Student *s = [[Student alloc] init]; Student *s1 = [s retain]; [s release]; [s release];
2> 由s1释放
Student *s = [[Student alloc] init];Student *s1 = [s retain];[s1 release];[s1 release];
- 两种方式都可以释放内存。
- 但是,如果没有一种统一的释放原则,那么就会造成代码的混乱,舍都可以释放, 好比一个公司所有的领导没有分工一样, 任何事儿, 任何一个领导都可以插一嘴,很显然这样就没法干了, 因此需要有一个规范去约束使用。
5.【掌握】单个对象内存管理(野指针)
单个对象的野指针问题
思考:对象在堆区的空间已经释放了,还能再使用p吗?
Person *p = [[Person alloc] init];[p release];// 因为P已经被释放,此时调用p的run方法,此时会报错。// 我们把p叫做野指针,把p指向的对象叫做僵尸对象。[p run];
野指针错误:访问了一块坏的内存(已经被回收的,不可用的内存)。
僵尸对象:所占内存已经被回收的对象,僵尸对象不能再被使用。(默认情况下xcode为了提高编码效率,不会时时检查僵尸对象,打开僵尸对象检测方法)
* 打开僵尸对象监测的方法
* 注意:
* 1> 空指针:没有指向任何东西的指针,给空指针发送消息不会报错.
关于nil和Nil及NULL的区别:
1.nil: A null pointer to an Objective-C object. ( #define nil ((id)0) )
- nil 是一个对象值。
- Person *p = [Person new];
- p = nil;
2.Nil: A null pointer to an Objective-C class.
- 如:Class someClass = Nil;给类对象赋值
3.NULL: A null pointer to anything else. ( #define NULL ((void *)0) )
- NULL是一个通用指针(泛型指针)。
4.NSNull: A class defines a singleton object used to represent null values in collection objects (which don’t allow nil values).
- [NSNull null]: The singleton instance of NSNull。
- [NSNull null]是一个对象,他用在不能使用nil的场合。
2> 不能使用[p retain]让僵尸对象起死复生。
- 3> 野指针操作
- 内存管理(1)
- 内存管理(1)
- 内存管理(1)
- 内存管理(1)
- 内存管理(1)
- 内存管理(1)物理内存描述
- 内存管理1(qdxx)
- c++内存管理(1)
- C++内存管理(1)
- OC 内存管理(1)
- OC--内存管理(1)
- 内存管理1(内核情景分析)
- linux与uclinux 内存管理(1)
- 80386虚模式内存管理(1)
- object c内存管理(1)
- C/C++内存管理(1)
- C++内存管理学习笔记(1)
- C++内存管理学习笔记(1)
- HTTPS图解过程
- 获取屏幕的宽高、当前手机的参数
- git使用总结
- JAVA 学习模块十九: 线程间通信
- 2.1.6&2.1.7 Value Object模式和业务代理模式
- 内存管理(1)
- c#-文件打开与保存,打开文件夹
- jQuery01
- php SOAP webservice
- 关于Vue.js数组的变动观测0
- Caffe 源码阅读笔记 [基本模块] Solver
- java设计模式笔记
- HTTP请求报文解析
- Android Volley框架使用详解