内存管理
来源:互联网 发布:网络视觉营销 编辑:程序博客网 时间:2024/05/22 12:25
1.内存区域
内存分为5个区:堆,栈,自由存储区,全局/静态存储区 和 常量存储区。
栈(stack):编译器需要时分配,不需要时自动清除的变量存储区。常是局部变量、函数参数等。
堆(heap):由new分配的内存块,编译器不负责释放,由应用程序去控制。一般一个new对应一个delete。若程序没有释放,在程序结束后,os自动回收。
例子:
void f()
{
int *p = new int [5];
}
思考:
那部分是堆,那部分是栈?
如何释放该块内存?是delete p 吗?
p是栈,int[5]是堆
p自动释放,int[5]是delete p。
内存管理是一个不易解决的问题。
需要时分配内存
在程序运行结束时释放内存
不要使用任何已经释放的内存
如何解决垂悬指针??
free(pint)
pint = NULL;
释放之后,置空
oc的内存管理使用引用计数,和半自动释放机制。
对象生命周期
包括:
诞生(通过alloc)
生存(接收消息和执行操作)
交友(借助方法的组合和参数)
释放(生命结束)
引用计数
又称保留计数,标示对象当前被引用的次数,标志对象使用寿命是否结束。
当前对象引用计数为0时,才能释放该对象占用的内存。
对象创建时,引用计数自动设置为1.
1.每个对象都又一个引用计数器(对栈)
代码访问一个对象时,将对象的保留计数器值加1.
访问结束保留计数器值减1
保留计数器值为0时,对象被销毁,其占用的内存将被系统收回。
2.利用alloc、new、或copy消息创建对象时:(对堆)
将对象的保留计数器置为1
发送retain消息,对象保留计数器加1;
发送release消息,对象保留计数器值减1;
发送retain count 消息时,获得保留计数器当前值。
保留计数器值为0时,系统自动发送一条dealloc消息,用户可重写该消息,但不可直接调用。
保留计数器常用方法:
-(id)retain;
-(void)release;
-(unsigned)retainCount;
使用实例:
[[car retain] setTire : tireAtIndex:2];
要求car对象保留计数器值加1并执行setTire操作
#import <Foundation/Foundation.h>@interface RetainTracker : NSObject {}@end@implementation RetainTracker-(id)init{ if(self = [super init]) {} return self;}-(void)dealloc{ [super dealloc];}@endint main (int argc, const char * argv[]){ RetainTracker *tracker = [RetainTracker new]; NSLog(@"%lu",[tracker retainCount]);//1 [tracker retain]; NSLog(@"%lu",[tracker retainCount]);//2 [tracker retain]; NSLog(@"%lu",[tracker retainCount]);//3 [tracker release]; NSLog(@"%lu",[tracker retainCount]);//2 [tracker retain]; NSLog(@"%lu",[tracker retainCount]);//3 [tracker release]; NSLog(@"%lu",[tracker retainCount]);//2 [tracker release]; NSLog(@"%lu",[tracker retainCount]);//1 [tracker release]; NSLog(@"%lu",[tracker retainCount]);//1 return 0;}
对象所有权
Engine *engine = [Engine new]; Car *car1 = [Car new]; Car *car2 = [Car new]; [car1 setEngine:engine]; [engine release]; [car2 setEngine:engine];
内存管理原则:
当一个对象的某个所有者需要使用它时,保证这个对象存在。
当一个对象的所有所有者都不再需要它时,保证这个对象被销毁。
只要任何一个所有者在使用完一个对象之后释放掉它,那么以上内存管理的目标就可以实现。
所有者应遵守:
拥有一个对象》使用一个对象》放弃对象的所有权
引用计数应遵守:
还需要这个对象时,保持对其增减为正。
不再需要这个对象时,保持对其增减为0。
自动释放池:
存放实体的池,这些实体是对象,能被自动释放。
给一个对象发送autorelease 消息时,实际上就是将该对象添加到nsautoreleasepool种。
当自动释放池被销毁时,会向该池种的所有对象发送release消息。
当使用new,alloc,或copy方法获得一个对象时,则需要在拥有该对象的对象的存方法种保留该对象。在拥有该对象的对象的dealloc方法种释放该对象。
当使用方法获得一个对象时,则需要在拥有该对象的对象的存方法种保留该对象。在拥有该对象的对象的dealloc方法种释放该对象。
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- String.format()方法的使用
- Zookeeper之Zab协议介绍(四)
- extern的作用(综合网络)
- iphone开发之SQLite使用详解
- Object Oriented Programming in C
- 内存管理
- 轻量级的C语言面向对象编程框架
- 文件系统API函数
- 互联网老兵:第一代程序员简晶 最老站长华军
- Android APK反编译详解(附图)
- uva 11218 - KTV
- 个人收录的各种命名法(只是我个人所知道的一些)
- Linux压缩命令
- Android 中的Parcelable与Serializalbe