首页 > 系统相关 >Objective-C内存管理机制概述

Objective-C内存管理机制概述

时间:2023-10-22 21:24:27浏览次数:38  
标签:对象 引用 管理机制 回收 ARC 垃圾 Objective MRC 内存

Objective-C管理的是分配在堆上的NSObject对象的内存,对其他非对象的C语言数据类型(int、char、float、double、struct、enum等)无效。

有以下3种方式:

  • 手工引用计数和自动释放池(MRC,Manual Reference Counting),又称手动保留释放(MRR,Manual Retain-Release)
  • 垃圾收集(GC,Garbage Collection)
  • 自动引用计数(ARC,Automatic Reference Counting)

 

自1980年代Objective-C诞生以来就使用支持MRC(或MRR)。该方式使用引用计数算法来管理内存。retain引用计数+1,release引用计数-1,当引用计数变为0则对象就会被销毁。

 

在2006年7月苹果全球开发者会议中,Apple宣布了Objective-C 2.0的发布,其增加了垃圾收集(GC)机制。

在2007年10月26日,Mac OS X 10.5 Leopard版本中实现了垃圾回收,在Mac环境提供了一个可选垃圾收集器。注:iOS上的Objective-C 2.0实现中不包含垃圾收集器。

在向后兼容模式中,Objective-C运行时会将引用计数操作retain与release变为无操作。

当垃圾收集启用时,所有的对象都是收集器的工作对象。使用__strong修饰的指针,标记其指向的对象仍在使用中。被标记为__weak的指针不被计入收集器的计数中,并在对象被回收时改写为nil。

垃圾收集器运行在一个低优先级的后台线程中,并可以在用户动作时暂停,从而保持良好的用户体验。

 

在2012年7月25日,Mac OS X 10.8 Mountain Lion和iOS5中引入了ARC,不再推荐使用GC(甚至声明将在未来版本中弃用GC),并在Xcode 4.3中提供了GC向ARC转换的工具。

最后,在2015年5月1日,苹果公司要求所有提交到App Store的Mac App及更新都不允许使用GC。注:详见Mac Apps That Use Garbage Collection Must Move to ARC

主要原因是由于GC过程会导致进程长时间得不到响应,内存不能及时回收导致占用高。

 

垃圾收集(GC,Garbage Collection)

① 全局变量和静态变量引用的NSObject对象不允许被回收, 栈内临时变量引用的NSObject对象也不允许被回收,这些对象称为根集合。

② 根集合中通过若弱引用连接的实例对象可被回收,并自动置nil。

③ NSObject对象被回收释放前会被执行finalize方法。

void *__strong NSALLocateCollectable(NSUInterger size, NSUInterger options);

//根据指针的声明不同 垃圾回收的规则也不同
//p1不是对象类型 被回收后会变成野指针
static void* p1 = NSALLocateCollectable(SZ, opt);
//p2是弱指针对象 被回收后会被nil
static __weak void* p2 = NSALLocateCollectable(SZ, opt);
//p3是强指针对象 不会被回收
static __strong void* p3 = NSALLocateCollectable(SZ, opt);

 

自动引用计数(ARC,Automatic Reference Counting)

通过编译器代码插入和Runtime支持,相比MRC,ARC让程序员不再需要书写retain/release/autorelease语句。

使用关键字__strong代替MRC模式下的retain(代表强引用,引用计数会+1),用__weak来代替MRC模式下的assgin(代表弱引用  注:assign为赋值属性),同时当__weak对象释放后会自动置为nil。

相比垃圾回收,ARC无法处理retaincycles(循环引用):如果两个对象互相强引用(strong references)将导致它们永远不会被释放,甚至没有任何对象引用它们。注:MRC也无法处理retaincycles

因此,尽管ARC能免去程序员大部分内存管理问题,但仍然要程序员自己避免retaincycles或手动打断对象之间的retain循环。

ARC和垃圾回收还有一个重要的不同:ARC不是强制的。而对于苹果的垃圾回收,要么整个程序都使用,要么都不用。

也就是说在app中的所有OC代码,包括所有的苹果框架和所有的第三方库必须支持垃圾回收,才能使用垃圾回收。

相反,ARC和MRC代码可以在一个app中和平共处,支持混编。这使得将项目可以零星地迁移到ARC,而不会像垃圾回收起初遇到的各种兼容性和稳定性的问题。

注:在ARC项目中,对MRC的文件可以添加编译选项-fno-objc-arc的标识;在MRC项目中,对ARC的文件可以添加编译选项 -fobjc-arc的标识。

 

参考

iOS Objective-C 中是否支持垃圾回收机制

 

标签:对象,引用,管理机制,回收,ARC,垃圾,Objective,MRC,内存
From: https://www.cnblogs.com/kekec/p/17781105.html

相关文章

  • 网络规划设计师真题解析--内存编址
    内存按字节编址,利用8K×4bit的存储器芯片构成84000H到8FFFFH的内存,共需()片。A.6      B.8      C.12      D.24答案:C解析:8FFFFH-84000H+1=C000HC000H转换成十进制:C*163+0*162+0*161+0*160=12*163=12*16*16*16=12*4*4*256=48*1024=48KC000H*8bit=48K*8bit(48......
  • 狂飙8000MHz!影驰HOF PRO DDR5-8000 24GB内存图赏
    影驰发布了旗舰内存HOFProDDR5-800024GB。现在这款新品已经来到了我们评测室,下面为大家带来图赏。影驰HOFPRODDR5-800024GB内存外观上沿用了系列一贯的银白配色,全新的纯白散热马甲采用了金属电泳白工艺。侧面造型细节部分则采用了金属喷砂工艺,标志性的亮银HOFLOGO在不......
  • 计算机语言的 堆内存 和栈内存有什么区别???
    在C语言中,堆内存和栈内存是两种不同的内存分配方式,它们有以下区别:.分配方式:栈内存:由编译器自动分配和释放,堆内存:需要手动分配和释放。.分配速度:栈内存:分配速度比堆内存快,因为它只需要移动栈指针即可,堆内存:分配需要在堆中搜索可用的空间。.内存管理:栈......
  • 使用LiME收集主机物理内存的内容时发生宕机
    作者pengdonglin137@163.com现象在一台ARM64的Centos7虚拟机里加载https://github.com/504ensicsLabs/LiME编译出的内核模块时发生宕机:insmodlime.kopath=/root/allmem.dumpformat=raw上面的目的是把机器物理内存的内容全部dump到文件中,大致的实现过程是,遍历系统中所有......
  • Go内存管理
    1.存储基础知识1.1计算机的存储体系从上至下依次是:CPU寄存器、Cache、内存、硬盘等辅助存储设备、鼠标等外接设备说明:从上至下,访问速度越来越慢,访问时间越来越长1.2内存1)物理内存通过物理内存条而获得的内存空间,这种存储是没有写入硬盘的,在计算机关机后就会丢失2)虚拟内......
  • Linux查看进程的CPU和内存使用情况
    ps-aux|grep"spring-native-hello"结果:chkusr106110.00.0131313253364pts/1Sl19:560:00./spring-native-hellochkusr131920.00.0112812972pts/1S+20:040:00grep--color=autospring-native-hello每列的含义:USER:这一......
  • vue项目运行内存不足 JS stacktrace
     因为node配置的环境变量默认是4096,如果vue项目过大,可能就会导致保存的时候,项目死掉。解决办法:1、我的电脑右键属性 2、搜索环境变量,点击编辑系统环境变量 3、点击环境变量4、更改默认值......
  • 嵌入式系统,内存不够了该怎么办?
    liwen012023.10.01前言在嵌入式系统中,内存是比较紧缺的资源,特别是在消费类产品中,为了节省成本,一般都会将硬件资源应用到极致。在开发过程中,就经常会遇到,运行内存(RAM)就还差一点,但就是不够用的情况,比如:需要在原系统上添加一个小算法OTA只能将固件放到内存上时需要动态分配......
  • C语言 内存布局
    GCC编译预处理->编译->汇编->链接预处理:头⽂件包含、宏替换、条件编译、删除注释...编译:主要进⾏词法、语法、语义分析等,检查⽆误后将预处理好的⽂件编译成汇编⽂件...汇编:将汇编⽂件转换成⼆进制⽬标⽂件...链接:将项⽬中的各个⼆进制⽂件+所需的库+启动代码链接成可执⾏⽂......
  • IntellIJ Idea内存不足时怎么设置
    IntellIJIdea内存不足时怎么设置现在越来越多的人投入了IntellIJIdea的怀抱,它给我们的日常开发带来了诸多便利,但是由于对它的不熟悉,导致很多时候需要某些设置却不知道怎么去哪里设置,比如,在我们导入大项目时,IntellIJIdea向我们抛出了一个OutOfMemoryError......