Rc Layout
#![allow(unused)]
fn main() {
let mut string = String::with_capacity(32); // sizeof::<String> = 24
string.push_str("Hello World! ");
let str1 = Rc::new(string); // sizeof::<RcInner<String>> = 40
// memory: strong: 1, weak: 1
assert_eq!(Rc::strong_count(&str1), 1);
assert_eq!(Rc::weak_count(&str1), 0);
let p1 = *(unsafe { &*(&str1 as *const Rc<_> as *const *const ()) }); // for debug the memory
println!("str1 = {:p}", p1);
let str2 = Rc::clone(&str1);
// memory: strong:2 weak: 1
assert_eq!(Rc::strong_count(&str2), 2);
assert_eq!(Rc::weak_count(&str2), 0);
let str3 = Rc::downgrade(&str2);
// memory: strong:2 weak: 2
assert_eq!(Rc::strong_count(&str1), 2);
assert_eq!(Rc::weak_count(&str1), 1);
drop(str1);
// memory: strong = 1, weak = 2
drop(str2);
// memory: strong = 0, weak = 1, the value is dropped in place
drop(str3);
// memory: strong = 0, weak = 0, the RcInner is dropped
println!("completed");
}
查看 p1 指向的内存:
#![allow(unused)]
fn main() {
struct Rc<T> {
ptr: NonNull<RcInner<T>>
}
struct RcInner {
strong: usize,
weak: usize,
value: T; // Here value: String
}
struct String {
vec: Vec<u8>
}
struct Vec<u8> {
buf: RawVec<u8>,
len: usize
}
struct RawVec<u8> {
inner: RawVecInner<u8>
}
struct RawVecInner {
ptr: Unique<u8>,
cap: usize
}
---
struct RcInner<String> { -- total: 40 bytes
strong: usize, // init:1, Rc +1,
weak: usize, // init:1 Weak +1
value: struct { -- total 24 bytes
buf: {
ptr: Unique<u8>
cap: usize,
}
len: usize
}
}
}

#![allow(unused)]
fn main() {
struct RcInner<String> {
strong: usize, // 1
weak: usize, // 1
value.buf.ptr: 0x60000091c100,
value.buf.cap: 0x20,
value.len: 0x0d
}
}
增加一个 Rc.clone()

增加一个 Weak 引用:

结论:
- 当 strong_count 为 0 时, RcInner.value 可以被 drop_in_place,即释放掉 String.ptr 所在 的内存。在这个例子中,释放掉 32个字节的内存(String.cap),但 RcInner 自身占用的 40 字节不被释放
- 当 weak_count 也为 0 时,RcInner 的内存也得以释放。
- Rc::new 时 strong = 1, weak = 1( Rc::weak_count() == weak - 1)
- Rc::clone 时 strong += 1, Rc::drop 时 strong -= 1
- 新建一个 Weak 时 weak += 1, Weak::drop 时 weak - = 1