Rust中Arc的实现原理是什么?为何仅占8字节?与Rc是否一致?
Rust中Arc与Rc的内存布局及实现逻辑
你的观察没错:64位系统下,Arc<T>和Rc<T>实例本身都只占用8字节内存,核心原因是它们的引用计数和数据都存储在堆上的控制块中,而实例本身仅仅是一个指向该控制块的指针。
为什么Arc只占8字节?
你原本以为需要指针+计数器的组合,但实际上计数器并没有存在Arc实例里:
Arc<T>实例本质是一个裸指针,指向堆上的ArcInner<T>结构体(控制块),这个结构体才包含:- 原子类型的强引用计数器(
AtomicUsize) - 原子类型的弱引用计数器
- 实际存储的数据
T
- 原子类型的强引用计数器(
- 64位系统下指针长度为8字节,所以
Arc<T>实例本身的大小就是8字节。
Rc的情况是否和Arc相同?
完全相同:
Rc<T>实例同样是一个指向堆上RcInner<T>控制块的指针,64位下占用8字节。- 唯一的区别是
RcInner<T>里的计数器是普通的usize而非原子类型——因为Rc仅用于单线程场景,不需要原子操作来保证线程安全,因此计数器的实现更轻量化,但这不影响Rc实例本身的内存占用。
简化的控制块示意(非官方源码)
可以用伪代码理解控制块的结构:
// Arc的控制块 struct ArcInner<T> { strong: AtomicUsize, weak: AtomicUsize, data: T, } // Rc的控制块 struct RcInner<T> { strong: usize, weak: usize, data: T, }
当你创建Arc::new(data)时,Rust会在堆上分配ArcInner<T>,然后返回一个指向它的指针作为Arc<T>实例。每次克隆Arc时,只会增加控制块里的强引用计数,而不会复制数据或增加实例本身的大小。
内容的提问来源于stack exchange,提问作者Test
相关产品推荐
相关产品推荐

