iOS中引用计数内存管理机制分析
来源:互联网 发布:java短信发送模板 编辑:程序博客网 时间:2024/05/17 23:38
操作系统的内存管理分成堆和栈。
在堆中分配的内存,都试用引用计数模式;在栈中则不是。
NSString定义的对象是保存在栈中,所以它没有引用计算。看一些书上说它的引用计算会是fffffffff最大整数,测试的结果显示它是-1.对该对象进行retain操作,不好改变它的retainCount值。
MutableNSString定义的对象,需要先分配堆中的内存空间,再初始化才能使用。它是采用引用计数管理内存的。对该对象做retainCount操作则每次增加一个。
其实,引用计数是对内存区域的空间管理方式,是应从内存块的视角去看的。任何对象都是指向它的指针,有多少个指针指向它,就有多少个引用计算。
如果没有任何指针指向该内存块了,很明显,该内存块就没有对象引用了,引用计算就是0,系统会人为该内存区域已经空闲,于是立即清理,也就是更新一下管理堆的链表中某个标示位。
(miki西游 @mikixiyou 原文链接: http://mikixiyou.iteye.com/blog/1592958)
测试方法如下:
在xcode中建立一个非arc的项目,单视图即可。建立一个按钮的操作方法。
- (IBAction)testRC:(id)sender {
NSInteger i;
i=self.i_test;
if((i%2)==1)
{
NSString * str1=@"welcome";
NSString * str2=@"mlgb";
NSString * str3;
NSString * str4=@"welcome";
NSLog(@"str1 addr is %p",str1);
NSLog(@"str2 addr is %p",str3);
NSLog(@"str3 addr is %p",str3);
NSLog(@"str4 addr is %p",str4);
NSLog(@"str1 retainCount is %i",[str1 retainCount]);
NSLog(@"str2 retainCount is %i",[str2 retainCount]);
//NSLog(@"str3 retainCount is %i",[str3 retainCount]);该使用会导致crash,因为str3没有指向任何内存区域。
str3=[str1 retain];
NSLog(@"str3=[str1 retain];");
NSLog(@"str1 retainCount is %i",[str1 retainCount]);
NSLog(@"str3 retainCount is %i",[str3 retainCount]);
str3=[str2 retain];
NSLog(@"str3=[str2 retain];");
NSLog(@"str2 retainCount is %i",[str1 retainCount]);
NSLog(@"str3 retainCount is %i",[str2 retainCount]);
/*
结果如下:
2012-07-14 11:07:38.358 testMem[878:f803] str1 addr is 0x3540
2012-07-14 11:07:38.360 testMem[878:f803] str2 addr is 0x0
2012-07-14 11:07:38.361 testMem[878:f803] str3 addr is 0x0
2012-07-14 11:07:38.362 testMem[878:f803] str4 addr is 0x3540
在栈中,内容相同的对象str1和str4,都分配在一个内存区域中,这点是c编译器的功能,有利于内存使用和效率。
2012-07-14 11:07:38.363 testMem[878:f803] str1 retainCount is -1
2012-07-14 11:07:38.364 testMem[878:f803] str2 retainCount is -1
2012-07-14 11:07:38.365 testMem[878:f803] str3=[str1 retain];
2012-07-14 11:07:38.366 testMem[878:f803] str1 retainCount is -1
2012-07-14 11:07:38.367 testMem[878:f803] str3 retainCount is -1
2012-07-14 11:07:38.367 testMem[878:f803] str3=[str2 retain];
2012-07-14 11:07:38.368 testMem[878:f803] str2 retainCount is -1
2012-07-14 11:07:38.369 testMem[878:f803] str3 retainCount is -1
*/
}
else
{
NSMutableString * mstr1=[[NSMutableString alloc] initWithString:@"welcome"];
NSMutableString * mstr2=[[NSMutableStringalloc]initWithString:@"mlgb"];
NSMutableString * mstr3;
NSMutableString * mstr4=[[NSMutableStringalloc]initWithString:@"welcome"];
NSLog(@"mstr1 addr is %p",mstr1);
NSLog(@"mstr2 addr is %p",mstr2);
NSLog(@"mstr3 addr is %p",mstr3);
NSLog(@"mstr4 addr is %p",mstr4);
NSLog(@"mstr1 retainCount is %i",[mstr1 retainCount]);
NSLog(@"mstr2 retainCount is %i",[mstr2 retainCount]);
//NSLog(@"mstr3 retainCount is %i",[mstr3 retainCount]);
mstr3=[mstr1 retain];
NSLog(@"mstr3=[mstr1 retain];");
NSLog(@"mstr1 retainCount is %i",[mstr1 retainCount]);
NSLog(@"mstr3 retainCount is %i",[mstr3 retainCount]);
NSLog(@"mstr3 addr is %p",mstr3);
mstr3=[mstr2 retain];
NSLog(@"mstr3=[mstr2 retain];");
NSLog(@"mstr2 retainCount is %i",[mstr1 retainCount]);
NSLog(@"mstr3 retainCount is %i",[mstr2 retainCount]);
NSLog(@"mstr3 addr is %p",mstr3);
/*
2012-07-14 11:07:36.652 testMem[878:f803] mstr1 addr is 0x68706b0
2012-07-14 11:07:36.655 testMem[878:f803] mstr2 addr is 0x6876040
2012-07-14 11:07:36.656 testMem[878:f803] mstr3 addr is 0x2a35
2012-07-14 11:07:36.657 testMem[878:f803] mstr4 addr is 0x686fbf0
2012-07-14 11:07:36.657 testMem[878:f803] mstr1 retainCount is 1
2012-07-14 11:07:36.658 testMem[878:f803] mstr2 retainCount is 1
2012-07-14 11:07:36.659 testMem[878:f803] mstr3=[mstr1 retain];
2012-07-14 11:07:36.660 testMem[878:f803] mstr1 retainCount is 2
2012-07-14 11:07:36.660 testMem[878:f803] mstr3 retainCount is 2
2012-07-14 11:07:36.661 testMem[878:f803] mstr3 addr is 0x68706b0
2012-07-14 11:07:36.662 testMem[878:f803] mstr3=[mstr2 retain];
2012-07-14 11:07:36.663 testMem[878:f803] mstr2 retainCount is 2
2012-07-14 11:07:36.663 testMem[878:f803] mstr3 retainCount is 2
2012-07-14 11:07:36.664 testMem[878:f803] mstr3 addr is 0x6876040
*/
}
self.i_test=self.i_test+1;
}
简而言之,引用计数实际上是指向其内存区域的指针数,从内存块的角度去理解,就很容易理解了。
- iOS中引用计数内存管理机制分析
- iOS中引用计数内存管理机制分析
- iOS中引用计数内存管理机制分析
- iOS中引用计数内存管理机制分析
- iOS中引用计数内存管理机制分析
- iOS内存管理机制解析之MRC手动引用计数机制
- OC 内存引用计数 内存管理机制
- OC 第四讲 内存管理机制,引用计数
- Cocos2dx内存管理之引用计数分析
- IOS内存管理--手动引用计数实现
- iOS内存管理之引用计数初识
- iOS(4)OC中内存管理机制
- Object-C中内存引用计数
- iOS中影响引用计数的方法
- 分析linux内存管理机制
- iOS内存管理机制
- ios内存管理机制转载
- ios中的内存管理机制
- Myeclipse打开xml properties jsp等文件乱码的终极解决方案
- 在altium designer中禁用USBJATG
- U盘里拷文件突然就断电文件丢失怎么办
- 如何查看Linux操作系统版本?
- handler机制(二)源码分析
- iOS中引用计数内存管理机制分析
- 获取字符串长度、宽度
- 硬链接与软链接
- 2014找工作总结-机会往往留给有准备的人
- 独立游戏设计宣言
- mysql 性能优化方案 (转)
- COCOS2D-X 抖动效果 CCShake
- 服务化的时代已经来临:学习dubbo有感
- Hibernate ,HQL