OC08,09-内存管理

内存管理

介绍

管理内存的常见方式

1.垃圾回收:java常见的管理内存的方式,系统来检测对象是否被使用,是否被释放

2.MRC手动管理引用计数,iOS管理内存的方式,程序员通过手动的方式来管理对象是否被释放

3.ARC自动管理引用计数,基于MRC,系统自动的管理内存,以后我们还是先使用MRC,培养管理内存的习惯

内存常见问题

  • 内存溢出
  • 野指针异常

iOS的内存管理

  • ARC
  • MRC

其中,MRC的内存管理机制是引用计数

内存管理机制

OC采用引用计数的机制,即一个新的引用指向对象的时候,引用计数器(retainCount)就递增,当释放掉一个引用的时候,计数器就递减.到0的时候调用dealloc,即释放占有的资源

影响引用计数的方法

+alloc

    // 对象被创建出来之后,他的引用计数retainCount就变成1
    Boy *boy = [[Boy alloc] init];
    NSLog(@"%ld",boy.retainCount);

结果:

2015-07-28 18:45:45.361 OC08,09_内存管理[2694:166290] 1

-retain

// retain:对对象的引用计数进行+1的操作
    [boy retain];
    [boy retain];
    [boy retain];
    NSLog(@"%ld",boy.retainCount);

结果:

2015-07-28 18:45:45.361 OC08,09_内存管理[2694:166290] 4

-release

    [boy release];
    NSLog(@"%ld",boy.retainCount);
    [boy release];
    [boy release];
    [boy release];

结果:

(最后是因为在类中声明了dealloc)

2015-07-28 19:04:21.023 OC08,09_内存管理[2721:171301] 3
2015-07-28 19:04:21.024 OC08,09_内存管理[2721:171301] 对象被释放

注意:当对象的引用计数1 -> 0的时候,会自动调用dealloc方法.dealloc才是对应对象释放的方法,并且注意,如果多次对对象进行release释放,会造成过度释放,过度释放也是最常见的内存问题.

当对象调用release的时候,它的引用计数是1,这个对象就不在对它的引用计数进行 -1 操作,而是直接调用dealloc方法,所以,在访问对象的引用计数的时候还是1

-autorelease

    Boy *boy = [[Boy alloc] init];

    [boy retain];
    [boy retain];
    NSLog(@"%ld",boy.retainCount);

    // release马上会把对象的引用计数-1,但是autorelease会延迟对对象的计数-1
    // 自动释放池
    // 只要对象用autorelease释放,会把对象放入到系统的自动释放池中,等出了池子的范围,对象引用计数自动-1,这个相当于java的垃圾回收,对象释放由系统来管理
    @autoreleasepool {
        [boy autorelease];
        NSLog(@"%ld",boy.retainCount);
    }
    NSLog(@"%ld",boy.retainCount);

-copy

copy也可以改变引用计数,但是他改变的是新对象的引用计数,而原先的对象计数不变

    NSArray *arr = @[@"1",@"2",@"3",@"4"];
    NSLog(@"%ld",arr.retainCount);
    NSArray *newArr = [arr copy];
  NSLog(@"%ld",newArr.retainCount);

结果:

2015-07-28 19:35:46.831 OC08,09_内存管理[3016:189709] 1
2015-07-28 19:35:46.832 OC08,09_内存管理[3016:189709] 2

内存管理的原则

凡是使用了alloc、retain或者copy让内存的引用计数增加了,就需要使用release或者autorelease让内存的引用计数减少。在一段代码内,增加和减少的次数要相等。

注意:便利构造器在返回对象的时候会加上一个autorelease,所以用便利构造器创建的对象不需要对内存进行内存管理

copy

跟retain不同,一个对象想要copy,生成自己的副本,需要实现 NSCopying协议,定义copy的细节(如何copy)。如果类没有接受NSCopying协议而给对象发送copy消息,会引起crash。

copy方法的实现

Boy.m

- (id)copyWithZone:(NSZone *)zone
{
    Boy *b = [Boy allocWithZone:zone];

    b.hobby = _hobby;
    b.name = _name;

    return b;
}

版权声明:本文为博主原创文章,转载请注明原文地址

时间: 2024-12-30 02:36:43

OC08,09-内存管理的相关文章

iOS OC08,09_内存管理

//管理内存有三种方式, //1.是垃圾回收,java常见的管理内存的方法,系统来检測对象是否被使用,是否被释放 //2.MRC手动管理引用计数,iOS管理内存的方式,程序猿通过手动的方式来管理对象是否被释放 //3.ARC自己主动管理引用计数,基于MRC,系统自己主动的管理内存,以后我们还是先使用MRC,培养管理内存的习惯 // // Girl.h // OC08,09_内存管理 // // Created by dllo on 15/7/27. // Copyright (c) 2015年

OC -内存管理

管理内存有三种方式 1:垃圾回收,在java中常见的管理内存方法,系统自动检测对象是否被使用,是否被释放 2.MRC: 手动管理引用计数,iOS管理内存的方式,程序员通过手动方式来管理对象是否被释放 3.ARC: 自动管理引用计数:基于MRC,系统自动的管理内存 引用计数:retainCount 当我们使用一个指针指向一块内存的时候,应该对这块内存做retain操作,引用计数+1.当我们不再使用这个指针指向这块内存,应该对这块内存做release操作,引用计数-1.这样可以使引用计数值一直保持等

OC08 -- 内存管理

一. 内存管理的三种方式 为什么要进行内存的管理呢? iOS程序会出现Crash(闪退)问题,90%以上都是因为内存问题. 内存问题体现在两个方面:内存溢出 .野指针异常. 内存溢出: iOS会给每个应用程序提供一定的内存,用于程序运行.而一旦超出了内存上限,程序就会Crash. 野指针异常: 对象内存空间已经被系统回收, 却仍然使用指针操作这块内存. 一. 垃圾回收(gc):java常见的管理内存的管理内存的方法,由系统自动来检测对象是否被使用,是否被释放. 二. MRC(Manual Ref

谈谈OC的内存管理 (2013-01-08 09:28:14)

苹果的内存有限,为了更好的用户体验,需要手动管理内存.从网上copy,也 一 基本原理 Objective-C的内存管理机制与Java那种全自动的垃圾回收机制是不同的,它本质上还是C语言中的手动管理方式,只不过稍加了一些自动方法. 1,OC采用了引用计数(retain count)对对象内存进行管理,例如,某个对象alloc了,那么这个对象的引用计数就加1,retain时加1,当对象不需要用时就需要销毁对象,释放内存,需要对象调用release方法,release会让引用计数减1,只有引用计数消

(转)从内存管 理、内存泄漏、内存回收探讨C++内存管理

http://www.cr173.com/html/18898_all.html 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对 C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++程序中都会发生,因此要想成为C++高手,内存管理一关是必须要过的,除非放弃 C++,转到Java或者.NET,他们的内存管理基本是自动的,当然你也放弃了自由和对内存的支配权,还放弃了C++超绝的性能

.NET内存管理、垃圾回收

1. Stack和Heap    每个线程对应一个stack,线程创建的时候CLR为其创建这个stack,stack主要作用是记录函数的执行情况.值类型变量(函数的参数.局部变量 等非成员变量)都分配在stack中,引用类型的对象分配在heap中,在stack中保存heap对象的引用指针.GC只负责heap对象的释 放,heap内存空间管理 Heap内存分配        除去pinned object等影响,heap中的内存分配很简单,一个指针记录heap中分配的起始地址,根据对象大小连续的分

C++内存管理(超长,例子很详细,排版很好)

[导语] 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++程序中都会发生,因此要想成为C++高手,内存管理一关是必须要过的,除非放弃C++,转到Java或者.NET,他们的内存管理基本是自动的,当然你也放弃了自由和对内存的支配权,还放弃了C++超绝的性能.本期专题将从内存管理.内存泄漏.内存回收这三个方面来探讨C++内存管理问题

C++内存管理(超长)

[导语] 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++程序中都会发生,因此要想成为C++高手,内存管理一关是必须要过的,除非放弃C++,转到Java或者.NET,他们的内存管理基本是自动的,当然你也放弃了自由和对内存的支配权,还放弃了C++超绝的性能.本期专题将从内存管理.内存泄漏.内存回收这三个方面来探讨C++内存管理问题

Oracle内存管理(之五)

[深入解析--eygle]学习笔记 1.4. 2其他内存组件 Large Pool-大池是SGA的一个可选组件,通常用于共享服务器模式(MTS). 并行计算或 RMAN的备份恢复等操作. Java Pool-Java池主要用于JVM等Java选件. Streams Pool-Streams pool是Oracle10g引入的概念,为Oracle的Streams功能所使用,如果不定义该参数,这部分内存将从Shread Pool中分配 对于SGA各部分内存分配,可以从数据库的视图中查询得到: 17: