深谈ARC机制



        ARC是iOS 5推出的新功能,全称叫 ARC(Automatic Reference Counting)。简单地说,就是代码中自动加入了retain/release,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。

        该机能在 iOS 5/ Mac OS X 10.7 开始导入,利用 Xcode4.2 可以使用该机能。简单地理解ARC,就是通过指定的语法,让编译器(LLVM 3.0)在编译代码时,自动生成实例的引用计数管理部分代码。有一点,ARC并不是GC,它只是一种代码静态分析(Static Analyzer)工具。

 

 通过一小段代码,我们看看使用ARC前后的变化点。


     

  1. @interface NonARCObject : NSObject {    
  2.     NSString *name;    
  3. }    
  4. -(id)initWithName:(NSString *)name;    
  5. @end    
  6.    
  7. @implementation NonARCObject    
  8. -(id)initWithName:(NSString *)newName {    
  9.     self = [super init];    
  10.     if (self) {    
  11.         name = [newName retain];    
  12.     }    
  13.     return self;    
  14. }    
  15.    
  16. -(void)dealloc {    
  17.     [name release];    
  18.     [Super dealloc];    
  19. }    
  20. @end    


  1. @interface ARCObject : NSObject {    
  2.     NSString *name;    
  3. }    
  4. -(id)initWithName:(NSString *)name;    
  5. @end    
  6.    
  7. @implementation ARCObject    
  8. -(id)initWithName:(NSString *)newName {    
  9.     self = [super init];    
  10.     if (self) {    
  11.         name = newName;    
  12.     }    
  13.     return self;    
  14. }    
  15. @end    



我们之前使用Objective-C中内存管理规则时,往往采用下面的准则
  • ✿   生成对象时,使用autorelease
  • ✿   对象代入时,先autorelease后再retain
  • ✿   对象在函数中返回时,使用return [[object retain] autorelease];

而使用ARC后,我们可以不需要这样做了,甚至连最基础的release都不需要了。

 使用ARC有什么好处呢?

  •  ✿  看到上面的例子,大家就知道了,以后写Objective-C的代码变得简单多了,因为我们不需要担心烦人的内存管理,担心内存泄露了
  •  ✿  代码的总量变少了,看上去清爽了不少,也节省了劳动力
  •  ✿  代码高速化,由于使用编译器管理引用计数,减少了低效代码的可能性 
  • ✿   记住一堆新的ARC规则 — 关键字及特性等需要一定的学习周期
  •  ✿   一些旧的代码,第三方代码使用的时候比较麻烦;修改代码需要工数,要么修改编译开关
  • ✿   retain, release, autorelease, dealloc由编译器自动插入,不能在代码中调用
  • ✿   dealloc虽然可以被重载,但是不能调用[super dealloc]

由于ARC并不是GC,并需要一些规则让编译器支持代码插入,所以必须清楚清楚了这些规则后,才能写出健壮的代码。

 ObjectiveC中的对象,有强参照(Strong reference)和弱参照(Weak reference)之分,当需要保持其他对象的时候,需要retain以确保对象引用计数加1。对象的持有者(owner)只要存在,那么该对象的强参照就一直存在。

对象处理的基本规则是
  •  ✿    只要对象的持有者存在(对象被强参照),那么就可以使用该对象
  •  ✿    对象失去了持有者后,即被破弃

 ARC中关于对象的引用参照,主要有下面几关键字。使用strong, weak, autoreleasing限定的变量会被隐式初始化为nil。

 

  • __strong

变量声明缺省都带有__strong关键字,如果变量什么关键字都不写,那么缺省就是强参照。

 

  • __weak

上面已经看到了,这是弱参照的关键字。该概念是新特性,从 iOS 5/ Mac OS X 10.7 开始导入。由于该类型不影响对象的生命周期,所以如果对象之前就没有持有者,那么会出现刚创建就被破弃的问题。


如果编译设定OS版本 Deployment Target 设定为这比这低的版本,那么编译时将报错(The current deployment target does not support automated __weak references),这个时候,我们可以使用下面的 __unsafe_unretained。

弱参照还有一个特征,即当参数对象失去所有者之后,变量会被自动付上nil (Zeroing)。

 

  • __unsafe_unretained

该关键字与__weak一样,也是弱参照,与__weak的区别只是是否执行nil赋值(Zeroing)。但是这样,需要注意变量所指的对象已经被破弃了,地址还还存在,但内存中对象已经没有了。如果还是访问该对象,将引起「BAD_ACCESS」错误。

 

  • __autoreleasing

该关键字使对像延迟释放。比如你想传一个未初始化的对像引用到一个方法当中,在此方法中实例化此对像,那么这种情况可以使用__autoreleasing。他被经常用于函数有值参数返回时的处理。

今天,我们看到了基本的ARC使用规则

  • ✿    代码中不能使用retain, release, retain, autorelease
  • ✿    不重载dealloc(如果是释放对象内存以外的处理,是可以重载该函数的,但是不能调用[super dealloc])
  • ✿    不能使用NSAllocateObject, NSDeallocateObject
  • ✿    不能在C结构体中使用对象指针
  • ✿    id与void *间的如果cast时需要用特定的方法(__bridge关键字)
  • ✿    不能使用NSAutoReleasePool、而需要@autoreleasepool块
  • ✿    不能使用“new”开始的属性名称 (如果使用会有下面的编译错误”Property’s synthesized getter follows Cocoa naming convention for returning ‘owned’ objects”)
VPP(Vector Packet Processing)的 **Feature 和 ARC(Adaptive Release Control)机制** 是其高性能数据包处理的核心设计,用于动态管理数据包处理路径和资源分配。以下是详细解析: --- ### **1. Feature 机制** #### **(1)基本概念** - **Feature** 是 VPP 中处理数据包的 **功能单元**(如 ACL、NAT、路由等),每个 Feature 对应一个处理节点(Node)。 - 数据包通过 **Feature Graph**(有向无环图)流动,每个节点处理特定功能后,决定数据包下一跳(Next Node)。 #### **(2)关键特性** - **动态编排**:Feature 可通过 CLI/API 动态启用或禁用,无需重启。 ```bash vppctl set interface feature <interface> <feature> [enable|disable] ``` - **优先级控制**:通过 `arc` 和 `next-node` 定义处理顺序。 - **批处理优化**:支持向量化处理(一次处理多个数据包)。 #### **(3)示例 Feature** - `ip4-input`:IPv4 输入处理。 - `acl-plugin-in-ip4-fa`:IPv4 ACL 过滤。 - `nat44-in2out`:NAT 转换。 --- ### **2. ARC 机制(Adaptive Release Control)** #### **(1)基本概念** - **ARC** 是 Feature 之间的 **依赖关系管理器**,确保数据包按正确顺序经过多个 Feature。 - 每个 ARC 定义一组可能的 **Next Nodes**,动态选择最优路径。 #### **(2)工作流程** 1. **注册 Feature 到 ARC**: ```c VNET_FEATURE_INIT (my_feature, static) = { .arc_name = "ip4-unicast", // 所属 ARC .node_name = "my-feature-node", }; ``` 2. **动态决策**: - 根据 Feature 的启用状态,ARC 自动构建处理路径。 - 例如:若 `acl-plugin` 启用,则 `ip4-unicast` ARC 的路径变为: ``` ip4-input → acl-plugin → ip4-lookup → ... ``` #### **(3)ARC 类型** - **内置 ARC**: - `ip4-unicast`:IPv4 单播流量处理。 - `ip4-multicast`:IPv4 组播流量处理。 - `device-input`:网卡输入流量处理。 - **自定义 ARC**:可通过插件扩展。 --- ### **3. Feature 与 ARC 的交互** #### **(1)数据包处理流程** ```mermaid graph LR A[device-input] --> B[ip4-input] B --> C{ip4-unicast ARC} C -->|acl enabled| D[acl-plugin] C -->|no acl| E[ip4-lookup] D --> E E --> F[interface-output] ``` #### **(2)性能优化** - **零拷贝**:Feature 间通过 `vlib_buffer_t` 传递数据包元数据,避免内存复制。 - **指令缓存友好**:高频 Feature 节点代码紧凑,减少 CPU 缓存失效。 --- ### **4. 调试与监控** #### **(1)查看 Feature 路径** ```bash vppctl show interface features <interface> ``` 输出示例: ``` Feature paths on GigabitEthernet0/0/0... ip4-unicast: ip4-input acl-plugin-in-ip4-fa ip4-lookup ``` #### **(2)性能统计** ```bash vppctl show runtime ``` 查看各 Node 的处理时间和包数。 --- ### **5. 应用场景** 1. **灵活功能组合** - 例如:在 `ip4-unicast` ARC 中插入自定义插件,实现流量分析。 2. **动态负载均衡** - 根据流量类型选择不同 Feature 路径(如加密流量跳过 ACL)。 3. **资源隔离** - 通过 ARC 分离关键路径(如控制平面和数据平面)。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值