Tagged Pointer 含义的解释

本文深入探讨了iOS中引入的TaggedPointer技术,旨在优化NSNumber、NSDate、NSString等小对象的存储效率。详细解释了在使用TaggedPointer前后,NSNumber对象的内存布局变化,以及Objc_msgSend如何识别并高效处理TaggedPointer。

一、含义

  • iOS 是在 64bit 开始,引入的 Tagged Pointer 技术
  • 用于优化 NSNumberNSDateNSString 等 小对象 的存储
    • 比如: 小型的 OC 对象,就可能用 Tagged Pointer 来实现
  • 在没有使用之前,NSNumber 等对象就是一个普通的OC 对象。需要动态分配内存、维护引用计数等,NSNumber 指针存储的是堆中 NSNumber 对象的地址值(跟其他的OC 对象没有任何区别)
    • 例如: NSNumber *number = [NSNumber numberWithInt: 10];
    • NSNumber * number = @(10);
    • NSNumber * number = @10;
    • 这三种写法 是等价的。
  • 使用之后, NSNumber 指针里面存储的数据变成了 :Tag + Data, 也就是将数据直接存储在了指针中
    • Tag : 标记,标记是 NSNumber 类型还是 NSDate 类型等
    • Data : 真正的数据
  • 当对象指针的最低有效位是1,则该指针为 Tagged Pointer
  • 当指针不够存储数据时,才会使用动态分配内存的方式来存储数据
  • Objc_msgSend 能够识别 Tagged Pointer , 比如 NSNumberintValue 方法, 直接从指针提取数据,节省了以前的调用开销。

二、解释 NSNumber 未使用 tagged Pointer 之前的内存

在这里插入图片描述

如图:NSNumber * number = @10; 是定义在 main 函数中的,所以是 局部变量。在函数中定义的局部变量放在 栈空间。
在这里插入图片描述

  • 如果 NSNumber 对象 的堆地址为 0x000001
  • 那么 栈空间内的 number 存储的就是 0x00001

存储堆内存的地址值

也就是说:如果想要将 10 这个值存储到系统中:

  • 首先要:alloc 一块 对空间
  • 在弄一个 指针变量 NSNumber *number
  • 在把 alloc 出来的堆内存空间地址给 number 指针

如果用 int 类型的话,才4个字节。但是到了 NSNumber 就这么复杂。
* int a = 10 ;

那么为什么要包装成 NSNumber 类型?

  • 因为 NSArrayNSDictionary 中不能存储 int 类型。所以只能包装成 NSNumber 类型。
  • *number 指针要8个字节
  • alloc 出来的对象最少要16个字节
  • 这样比 int 类型要多很多
  • 所以苹果 引进了 tagged Pointer 这个技术

三、解释 NSNumber 使用 tagged Pointer 之后的内存
在这里插入图片描述
这个里面,相当于只用了8个字节,就保存了 值

例如:
在这里插入图片描述

打印结果是:
0x127,0x227,0x327

在这里插入图片描述

打印结果是:
0x427,0x527,0x627

如果存储的数很大
NSNumber *number = @(0xFFFFF);
NSLog(@"%p", number);

打印结果:0x102b292d0
这个地址很明显是一个堆空间的地址

也就是说:如果 tagged pointer 8 个控件放不下的话。就变成了堆空间地址。

在这里插入图片描述

五、Objc_msgSend 能够识别 Tagged Pointer

NSNumber *number1 = @4
// 运行时是 objc_msgSend(number1, @selector(intValue))
int a =  [number1 intValue];
  • objc_msgSend(number1, @selector(intValue)) 这句话的意思大家都知道。就是:通过 number1isa 指针找到 number1 的类对象,去它的类对象里面找 intValue 方法。
  • 但是 number1 是采用tagged pointer 技术实现的。没有经过 alloc 也就没有堆空间,也不存在isa。因为 tagged pointer 就一个指针,指针里面存储的东西就是 tag + data

objc_msgSend方法里面会 进行判断,有没有使用 tagged pointer技术,如果有使用,就不会再去 拿 isa 在找东西。

  • 它会 直接把 值从 指针中抽取出来。
发生crash 原因 03-29 00:44:51.647997 11218 17700 F libc : fdsan: attempted to close file descriptor 568, expected to be unowned, actually owned by unique_fd 0x6fec1a944c 03-29 00:44:51.649092 11218 17700 F libc : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 11218 (platform-back-h), pid 11218 (platform-back-h) 03-29 00:44:54.514753 11244 11244 F DEBUG : Process name is com.ss.android.article.news, uid is 10286, not key_process 03-29 00:44:54.515717 11244 11244 F DEBUG : keyProcess: 0 03-29 00:44:54.515738 11244 11244 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 03-29 00:44:54.515753 11244 11244 F DEBUG : Build fingerprint: 'OPPO/PKV110/OP5DFB:15/AP3A.240617.008/V.1cb6077-15b3e-19a53:user/release-keys' 03-29 00:44:54.515767 11244 11244 F DEBUG : Revision: '0' 03-29 00:44:54.515777 11244 11244 F DEBUG : ABI: 'arm64' 03-29 00:44:54.515788 11244 11244 F DEBUG : Timestamp: 2025-03-29 00:44:52.092843339+0800 03-29 00:44:54.515800 11244 11244 F DEBUG : Process uptime: 1s 03-29 00:44:54.515819 11244 11244 F DEBUG : Cmdline: com.ss.android.article.news 03-29 00:44:54.516387 11244 11244 F DEBUG : pid: 11218, tid: 11218, name: platform-back-h >>> com.ss.android.article.news <<< 03-29 00:44:54.516431 11244 11244 F DEBUG : uid: 10286 03-29 00:44:54.516450 11244 11244 F DEBUG : tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE) 03-29 00:44:54.516466 11244 11244 F DEBUG : signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr -------- 03-29 00:44:54.516481 11244 11244 F DEBUG : Abort message: 'ubsan: pointer-overflow by 0x00000076fa8ed160' 03-29 00:44:54.516507 11244 11244 F DEBUG : x0 0000000000000000 x1 0000000000002bd2 x2 0000000000000006 x3 0000007704a089e0 03-29 00:44:54.516520 11244 11244 F DEBUG : x4 631f646b68651f64 x5 631f646b68651f64 x6 631f646b68651f64 x7 7f7f7f7f7f7f7f7f 03-29 00:44:54.516532 11244 11244 F DEBUG : x8 00000000000000f0 x9 00000076f248a378 x10 0000000
04-01
<think>我们正在讨论华为交换机的Hybrid端口配置,特别是关于如何配置端口的taggedVLAN功能。根据用户当前的需求,他们想了解或配置与VLANtagged相关的网络设置,特别是“porthybridtaggedvlanconfiguration”。参考用户之前的对话历史:-用户之前询问了关于配置Hybrid端口的untaggedVLAN(VLAN10和20)。-现在用户转向taggedVLAN配置。参考引用内容:-引用[4]提供了配置示例:`porthybridtaggedvlan23`,表示配置hybrid类型端口在通过vlan2和3数据时,都携带标签[^4]。-引用[2]提到,tagged和untagged配置在同一个VLAN上可能存在矛盾(例如,同时配置了同一个VLAN为tagged和untagged),并指出PVID的优先级更高(即从该VLAN发出的包不带标签)[^2]。-引用[5]指出,Hybrid接口是华为设备特殊的二层接口模式,可以同时允许多个VLAN的流量通过并选择是否打标签[^5]。因此,针对用户的当前问题,我们需要解释如何配置Hybrid端口的taggedVLAN,以及相关注意事项。###配置Hybrid端口的TaggedVLAN在华为交换机上,使用`porthybridtaggedvlan`命令可以指定哪些VLAN的流量在通过该端口时保留标签(即带标签发送)。这种配置常用于连接其他交换机或支持VLAN标记的设备(如IP电话、无线AP或服务器)。####配置步骤:1.**进入系统视图**:登录交换机,进入系统配置模式。```bashsystem-view```2.**进入接口视图**:选择需要配置的接口。```bashinterfaceGigabitEthernet0/0/2```3.**设置端口模式为Hybrid**:如果接口不是Hybrid模式,需要先设置。```bashportlink-typehybrid```4.**配置TaggedVLAN**:指定哪些VLAN的流量以带标签方式发送。```bashporthybridtaggedvlan2030```上述命令配置该端口发送属于VLAN20和30的流量时保留VLAN标签[^4][^5]。5.**(可选)配置PVID**:设置端口的默认VLAN。当端口收到未标记的帧时,会将其归类到PVID指定的VLAN。```bashporthybridpvidvlan10```注意:如果配置了某个VLAN(如VLAN10)为tagged,同时又将其设置为PVID,则会产生冲突(参考引用[2])[^2]。一般情况下,PVID对应的VLAN通常配置为untagged(这样从该VLAN发出的帧将不带标签)。6.**(可选)配置UntaggedVLAN**:如果需要某些VLAN以不带标签方式发送,可以同时配置。```bashporthybriduntaggedvlan1040```注意:同一个VLAN不能同时配置为tagged和untagged,否则配置无效(系统可能会报错)[^2]。7.**退出并保存配置**:```bashquitsave```####配置示例假设我们有一个端口(GigabitEthernet0/0/2),需要实现:-未标记(untagged)的VLAN:10(用于连接普通PC)-带标记(tagged)的VLAN:20,30(用于连接另一个支持VLAN的交换机)配置命令:```bashsystem-viewinterfaceGigabitEthernet0/0/2portlink-typehybridporthybridpvidvlan10#设置PVID为10,确保收到的未标记帧被归类到VLAN10porthybriduntaggedvlan10#发送VLAN10的帧时不带标签porthybridtaggedvlan2030#发送VLAN20和30的帧时保留标签quitsave```####注意事项1.**PVID和untaggedVLAN的协调**:-一个端口只能有一个PVID(默认VLAN),通常建议将PVID设置为你希望作为“本地VLAN”的VLAN,并且将该VLAN配置为untagged。-如果PVID对应的VLAN被配置为tagged,那么从该VLAN发出的帧会去掉标签(因为tagged配置要求保留标签,PVID又要求去掉标签,矛盾)。引用[2]指出,PVID优先级更高,即实际效果是untagged[^2]。2.**同一VLAN禁止同时tagged和untagged**:-例如,不能同时配置`porthybriduntaggedvlan20`和`porthybridtaggedvlan20`。如果有这种冲突,交换机会忽略其中一个配置,具体取决于配置顺序(实际使用中应避免这种情况)。3.**默认VLAN(VLAN1)的处理**:-默认情况下,Hybrid端口会允许VLAN1的流量。从安全角度,建议禁用VLAN1(尤其是未使用的端口),可通过`undoporthybridvlan1`禁止VLAN1通过[^3]。4.**验证配置**:-使用`displayportvlan`命令查看端口VLAN信息。-使用`displayinterface`命令查看端口详细状态。5.**应用场景**:-TaggedVLAN常用于级联交换机、服务器(需要识别多个VLAN)等场景。-UntaggedVLAN常用于连接PC、打印机等不支持VLAN标记的设备。###相关问题1.在什么情况下需要配置多个taggedVLAN?请举例说明(例如,连接交换机或虚拟化服务器)[^4]。2.如何检查Hybrid端口的配置是否生效?(例如,通过`displayportvlan`或`displayinterface`命令)[^4][^5]。3.如果在同一个端口上同时配置了某个VLAN为tagged和untagged,会发生什么?如何解决冲突?(参考引用[2]的结论:PVID配置优先级更高)[^2]。4.如何从安全角度优化Hybrid端口的VLAN配置(如禁止未使用的VLAN,特别是VLAN1)[^3]?</think> ### 配置Hybrid端口的Tagged VLAN 在华为交换机中,`port hybrid tagged vlan`命令用于配置**标记流量(tagged traffic)**,表示从该端口发送特定VLAN的数据帧会保留VLAN标签。这种配置主要用于以下场景: - 连接其他支持VLAN的交换机或路由器 - 连接需要多VLAN通信的服务器 - 连接支持VLAN标记的终端设备(如IP电话、无线AP) #### 配置步骤(以Huawei交换机为例): 1. **创建VLAN**(若未创建): ```bash system-view vlan batch 10 20 30 40 # 创建需要的VLAN[^4] ``` 2. **配置Hybrid端口模式**: ```bash interface GigabitEthernet0/0/1 # 进入目标端口 port link-type hybrid # 设置端口为hybrid模式[^4] ``` 3. **配置Tagged VLAN**: ```bash port hybrid tagged vlan 10 20 30 # 允许VLAN10/20/30的流量带标签发送[^4] ``` 4. **配置Untagged VLAN和PVID**(可选但推荐): ```bash port hybrid untagged vlan 40 # 设置VLAN40为未标记流量 port hybrid pvid vlan 40 # 设置默认PVID为VLAN40[^1] ``` 5. **验证配置**: ```bash display port vlan # 查看端口VLAN配置[^4] display interface GigabitEthernet0/0/1 # 查看端口详细信息 ``` #### 关键特性与注意事项: 1. **Tagged vs Untagged的区别**: - **Tagged**:保留VLAN标签($$ \text{Frame} + \text{VLAN Tag} $$),用于设备间的VLAN识别 - **Untagged**:剥离VLAN标签($$ \text{Frame} $$),用于连接终端设备[^4] 2. **PVID的作用**: - 处理**入方向未标记帧**时分配到指定VLAN(如PVID=40) - 当**出方向流量**的VLAN与PVID相同时: - 若配置为`tagged`,仍带标签发送 - 若配置为`untagged`,则剥离标签发送[^2] 3. **安全配置建议**: ```bash undo port hybrid vlan 1 # 禁用默认VLAN1(安全加固)[^3] port hybrid tagged vlan 10 20 30 only # 显式指定允许的VLAN ``` 4. **典型应用场景**: **网络拓扑**: ``` [服务器]----(Hybrid端口)----[交换机]----(Trunk端口)----[路由器] Tagged: 10,20,30 Untagged: 40 (PVID) ``` - 服务器接收多VLAN数据(VLAN10/20/30带标签) - 服务器发送未标记流量默认归类到VLAN40 #### 配置示例 ```bash system-view vlan batch 10 20 30 40 interface GigabitEthernet0/0/24 port link-type hybrid port hybrid pvid vlan 40 port hybrid untagged vlan 40 port hybrid tagged vlan 10 20 30 undo port hybrid vlan 1 # 禁用VLAN1 quit save ``` ### 相关问题 1. 当同一VLAN同时配置为tagged和untagged时会发生什么冲突?如何解决?[^2] 2. 如何在Hybrid端口上配置VLAN过滤,仅允许特定tagged VLAN通过?[^3] 3. 相比Trunk模式,Hybrid模式在连接服务器时有哪些优势?[^5] 4. 如何验证tagged VLAN配置的连通性(如使用带VLAN标记的ping测试)?[^4] > 注:实际配置前请确认交换机型号和OS版本,部分命令可能因设备不同存在差异。生产环境建议先在测试环境验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值