内存管理

内存在Objective-C开发中是一种相对稀缺的资源,拿Iphone4为例,它的内存只有512mb,所以妥善的处理好所创造,所使用的每个对象与变量都将成为一个问题。在ARC出现以前,同大部分基于C的编程语言一样,程序员需要考虑如何高效的管理内存。像在Java或是一些脚本语言中就不需要考虑内存管理的问题。

生命周期





Obj-c对象的创建,存活和销毁整个过程为它的声明周期。销毁后就会回收对象占用的内存。那么跟踪对象的使用,以及理解在什么时候释放资源十分重要。

看到这样一个问题,问为什么不在dealloc中release viewController而是立即释放呢?

MainViewController *viewController = [[MainViewController alloc] initWithNibName:@"MainView" bundle:nil];
self.mainViewController = viewController;
[viewController release];

其实理解了持有者的作用就能很快回答,指针viewController在这里只是负责一个MainViewController的创建,以及给mainViewController传值的一个作用,之后它的存在并没有意义了,所以立即release掉来消除引用。

在频繁的增加持有者的时候,可以用retainCount属性来跟踪持有者的个数,当然在一些难以确定的区域,也可以借助autorelease来帮助管理。
内存管理好比于保安开和锁住大门。当人要进入公司工作时,先要打卡声明来工作了,走的时候也打卡说明下班了,当所有人都走了之后,保安才能锁住大门,提前锁或不锁都会出现一些问题。

一般来讲,内存管理遵循一些原则:
1.自己生成的对象,自己持有它(生成并持有的方法一般为:alloc,new,copy,mutableCopy)
2.不是自己生成的对象,自己也能持有
3.不再需要自己持有的对象,立即释放
4.不能释放不是自己持有的对象

内部实现


因为苹果公司不开源的原因,很多研究只能去看GNUstep来说明,GNUstep是Cocoa框架的互换框架。虽然不是完全相同,但从实现来说,应该是十分相近的。

+ alloc方法

alloc方法调用 +allocWithZone:

+ (id)allocWithZone:(NSZone *)z
{

return NSAllocateObject(self, 0, z); //这个方法负责分配内存空间并返回作为对象使用的id类型。

}

那么引用计数呢?

引用计数其实也是保存在一个结构体
struct obj_layout {
NSUInteger retained;
};
alloc类方法用这个结构体来保存引用计数并将其保存在头部,每调用一次alloc,指向结构体的指针给retained + 1。
那么访问retained的方法自然就去访问对象指针的头部
return ((struct obj_layout *) anObject)[-1].retained + 1; //anObject为传入的参数,理解为调用者本身(self)

那么,retain方法就会使上面的retained值自增1,release方法减1。

dealloc时,
struct obj_layout *o = &((struct obj_layout *) anObject)[-1];
free(o);
来废弃该结构体。

在《Objective-c 高级编程》中,作者给出了对苹果实现的猜测。大体思想还是类似的,不过存储方式貌似发生了改变,上面是将引用计数存储在了对象内存块的头部,而苹果实现,将其保存在了引用计数表的记录中。并且各自的好处如下:

头部管理:
少量代码即可完成。
能够统一管理引用计数用的内存块与对象用的内存块。

引用计数表管理:
对象用内存块的分配无需考虑内存块头部。
引用计数表各记录中存有内存块地址,可从各个记录追溯到各对象的内存块。


autorelease


经过autorelease的对象,不需要由我们手动去管理内存,而是由自动释放池(Autoreleasepool)来进行管理。尽管如此,只要不废弃AutoreleasePool对象,那么生成的对象就不能被释放,有时可能会产生内存不足的现象。所以要注意释放池的使用。

来看一下GNUstep对autorelease的实现
- (id)autorelease
{
[NSAutoreleasePool addObject:self];
}
在NSAutoreleasePool中对addObject:方法的实现
- (void)addObject:(id)anObj
{
[array addObject:anObj];
}

再来看下其他方法
- (void)drain
{
[self dealloc];
}

- (void)dealloc
{
[self emptyPool];
[array release];
}

- (void)emptyPool
{
for (id obj in array) {
[obj release];
}
}

那么,如果autorelease NSAutorelease对象会怎么样呢?
答案是肯定的,发生异常:不能自动释放一个自动释放池。

当然,自动释放池可以嵌套使用
@autorelease {
@autorelease {
 

code...

 
}
}

以上是本篇文章的全部内容,欢迎指正和讨论。转载注明出处~

再谈内存管理与ARC运行机制(一)的更多相关文章

  1. OC的内存管理(二)ARC

    指针: 指向内存的地址指针变量 存放地址的变量指针变量值 变量中存放的值(地址值)指针变量指向的内存单元值 内存地址指向的值1):强指针:默认的情况下,所有的指针都是强指针,关键字strong ):弱 ...

  2. JVM原理(Java代码编译和执行的整个过程+JVM内存管理及垃圾回收机制)

    转载注明出处: http://blog.csdn.net/cutesource/article/details/5904501 JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.e ...

  3. V8 内存管理和垃圾回收机制总结

    这篇文章主要介绍 V8 的内存管理和垃圾回收知识. V8 内存管理及垃圾回收机制浅析 由于 V8 引擎的原因,Node 在操作大内存对象时受到了一些限制,在 64 位的机器上,默认最大操作的对象大小约 ...

  4. [转载]再谈PostgreSQL的膨胀和vacuum机制及最佳实践

    本文转载自 www.postgres.cn 下的文章: 再谈PostgreSQL的膨胀和vacuum机制及最佳实践http://www.postgres.cn/news/viewone/1/390 还 ...

  5. C学习笔记(11)--- 可变参数,浅谈内存管理 【C基础概念系列完结】

    1.可变参数(variable arguments): 可变参数允许您定义一个函数,能根据具体的需求接受可变数量的参数. int func(int, ... )             (函数 fun ...

  6. JVM内存管理和垃圾回收机制介绍

    http://backend.blog.163.com/blog/static/20229412620128233285220/     内存管理和垃圾回收机制是JVM最核心的两个组成部分,对其内部实 ...

  7. JVM的生命周期、体系结构、内存管理和垃圾回收机制

    一.JVM的生命周期 JVM实例:一个独立运行的java程序,是进程级别 JVM执行引擎:用户运行程序的线程,是JVM实例的一部分 JVM实例的诞生 当启动一个java程序时.一个JVM实例就诞生了, ...

  8. 内存管理、ARC

    内存管理 一.基本原理 1.什么是内存管理 移动设备的内存极其有限,每个app所能占用的内存是有限制的 当app所占用的内存较多时,系统会发出内存警告,这时得回收一些不需要再使用的内存空间.比如回收一 ...

  9. java基础(一):谈谈java内存管理与垃圾回收机制

    看了很多java内存管理的文章或者博客,写的要么笼统,要么划分的不正确,且很多文章都千篇一律.例如部分地方将jvm笼统的分为堆.栈.程序计数器,这么分太过于笼统,无法清晰的阐述java的内存管理模型: ...

随机推荐

  1. asp.net MVC FileResult在IE下异常的解决办法

    var encoding = System.Text.Encoding.UTF8; Response.Charset = encoding.WebName; Response.HeaderEncodi ...

  2. 降维(一)----说说主成分分析(PCA)的源头

    降维(一)----说说主成分分析(PCA)的源头 降维系列: 降维(一)----说说主成分分析(PCA)的源头 降维(二)----Laplacian Eigenmaps --------------- ...

  3. Hicharts弄个样例

    前端的事情,但最好自己要了解一下,能作个最简单的东东出来... 样例,需要的时候,用用,就喟给它一样模板数据即可. PYTHON,把字典的键值和KEY值匹配成列表即可. $(function () { ...

  4. 今天,安装了一个GANGLIA玩玩,以后再测试NAGIOS吧。

    说不定以后派得上用场呢.. 还有,NGINX也要学,不能老是凭站IIS,APACHE混饭吃吧,现在它都这么流行了..新浪,网易,腾讯.

  5. IIS tomcat共用80端口解决一个IP多个域名:使用Nginx反向代理方式使两者兼容

    环境: windows server 2003,IIS6服务器,Tomcat7服务器 域名有几个: 以下是使用IIS的域名: http://www.formuch.com/ http://www.fo ...

  6. 【UVA 1395】 Slim Span (苗条树)

    [题意] 求一颗生成树,满足最大边和最小边之差最小 InputThe input consists of multiple datasets, followed by a line containin ...

  7. Jrtplib

    RTP/RTCP 视频数据传输 (续) http://blog.csdn.net/neohuo/article/details/821442

  8. xbmc

    XBMC是一个优秀的自由和开源的(GPL)媒体中心软件.XBMC最初为Xbox而开发,可以运行在Linux.OSX.Windows.Android4.0系统.XBMC能够播放几乎所有流行的音频和视频格 ...

  9. USB otg 学习笔记

    1 USB OTG的工作原理 OTG补充规范对USB2.0的最重要的扩展是其更具节能性的电源管理和允许设备以主机和外设两种形式工作.OTG有两种设备类型:两用OTG设备(Dualrole device ...

  10. 虚拟机安装了ubuntu,忘记密码修复

    在虚拟机中按照以下步骤重新为用户设定新密码. 重启Ubuntu,随即长按shift进入grub菜单: 选择recovery mode,回车确认: 在Recovery Menu中,选择“Root Dro ...