学习笔记八——内存管理相关

📘 目录

  1. 内存结构基础:栈、堆、数据段
  2. Rust 的内存管理机制(对比 C/C++、Java)
  3. Drop:Rust 的自动清理机制
  4. Deref:为什么 *x 能访问结构体内部值
  5. Rc:多个变量"共享一个资源"怎么办?
  6. Weak:如何打破 Rc 的循环引用?
  7. borrow_mut 和 downgrade 是什么意思?
  8. 👁 Rc / Weak / Deref / Drop 关系图
  9. 总结 & 使用建议

1️⃣ 内存结构基础

Rust 程序运行时,内存大致分为:

区域 用途说明 生命周期
存储函数调用的局部变量 函数调用期间
存储动态分配的大对象 显式释放或自动释放
数据段 静态变量、全局变量等 程序运行全过程

2️⃣ Rust 的内存管理机制

  • Rust 不靠垃圾回收器
  • 通过"所有权 + 借用"系统管理内存
  • 编译时就能判断内存是否正确释放
rust 复制代码
fn main() {
    let s = String::from("hello");
    let t = s;
    // println!("{}", s); // ❌ 错误:s 的所有权已经被转移给 t
}

3️⃣ Drop:变量作用域结束自动释放

你可以实现 Drop trait,在变量被释放时自动执行逻辑。

rust 复制代码
struct Connection;

impl Drop for Connection {
    fn drop(&mut self) {
        println!("连接关闭!");
    }
}

fn main() {
    let _conn = Connection;
    println!("连接中...");
}
// 输出:连接中... ➤ 连接关闭!

4️⃣ Deref:让结构体支持 *x

Rust 中 *x 默认是用于"解引用"指针或引用。如果你想让自己写的结构体也支持 *x,就需要实现 Deref

rust 复制代码
use std::ops::Deref;

struct MyBox<T>(T);

impl<T> Deref for MyBox<T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        &self.0 // 访问结构体里的第一个字段
    }
}

5️⃣ Rc:多个变量想"共同拥有"一个资源?

默认变量所有权不能共享:

rust 复制代码
let a = String::from("hi");
let b = a; // a 不再拥有字符串

如果你希望多个变量共享一个资源(比如多个节点共享同一根节点),可以用:

rust 复制代码
use std::rc::Rc;

let a = Rc::new(String::from("hello"));
let b = Rc::clone(&a);  // ✅ 不是深拷贝,只是计数 +1
let c = Rc::clone(&a);

6️⃣ Weak:如何解决 Rc 的循环引用?

🌀 什么是循环引用?

rust 复制代码
a → b → a   // 永远互相指着,永远无法释放

✅ Weak 是什么?

  • Rc<T>:是"强引用",决定资源释放
  • Weak<T>:是"弱引用",不会影响资源生命周期

7️⃣ borrow_mut 和 downgrade 是什么意思?

🔹 borrow_mut 是什么?

当你使用 RefCell<T> 来包裹一个值时,可以在运行时借用它的可变引用。

rust 复制代码
use std::cell::RefCell;

let x = RefCell::new(5);
*x.borrow_mut() = 10;  // ✅ 可变借用并修改

解释:

  • .borrow_mut():是 RefCell 提供的方法
  • 它返回一个可变引用,类似于 &mut T,但是在运行时检查是否有冲突

📌 注意:不能同时有可变和不可变借用,否则运行时会 panic。


🔹 downgrade 是什么?

Rc::downgrade(&rc) 是把一个 Rc<T> 强引用变成 Weak<T> 弱引用。

rust 复制代码
let strong = Rc::new(String::from("Rust"));
let weak = Rc::downgrade(&strong); // 不增加引用计数

可以用 weak.upgrade()Weak 转回 Rc,如果值还活着,就返回 Some(Rc),否则是 None


🧪 示例:父子节点用 Weak 打破循环引用

rust 复制代码
use std::rc::{Rc, Weak};
use std::cell::RefCell;

struct Node {
    value: i32,
    parent: RefCell<Option<Weak<Node>>>,  // 👈 防止循环引用
    children: RefCell<Vec<Rc<Node>>>,
}

fn main() {
    let parent = Rc::new(Node {
        value: 1,
        parent: RefCell::new(None),
        children: RefCell::new(vec![]),
    });

    let child = Rc::new(Node {
        value: 2,
        parent: RefCell::new(Some(Rc::downgrade(&parent))),  // 🔥 不增加计数
        children: RefCell::new(vec![]),
    });

    parent.children.borrow_mut().push(child.clone());

    // 程序结束时能正确释放所有节点
}

8️⃣ 👁 Rc / Weak / Deref / Drop 关系图

复制代码
   ┌────────────┐
   │ Rc<T>      │◄─────┐
   └────────────┘      │ Rc::clone()
        ▲              │
        │              │
        │ Rc::downgrade│
        ▼              │
   ┌────────────┐      │
   │ Weak<T>    │────┐ │
   └────────────┘    │ │
        │            │ │
        │ upgrade()  ▼ ▼
        │       ┌─────────┐
        │       │ *x 解引用│(Deref)
        ▼       └─────────┘
   drop()(当 Rc 引用数为 0 自动触发)

✅ 总结 & 建议

工具 功能说明 典型使用场景
Rc<T> 多个所有者,共享资源 单线程共享结构,如树结构
Weak<T> 不增加计数,防止循环引用 父指向子用 Rc,子指向父用 Weak
RefCell<T> 运行时可变借用检查 单线程内部可变性
borrow_mut 在 RefCell 中获取可变引用 RefCell<i32>.borrow_mut()
downgrade 将 Rc 转为 Weak,不影响引用计数 避免结构间强依赖
Deref 让自定义类型也能用 *x 访问内部值 智能指针封装
Drop 离开作用域时自动释放资源 自动释放连接、缓存等

相关推荐
美味的大香蕉1 小时前
Spark SQL
笔记
轻闲一号机2 小时前
【机器学习】机器学习笔记
人工智能·笔记·机器学习
天下琴川3 小时前
Dify智能体平台源码二次开发笔记(5) - 多租户的SAAS版实现(2)
人工智能·笔记
CarnivoreRabbit4 小时前
Beamer-LaTeX学习(教程批注版)【2】
学习·latex·beamer
凡人的AI工具箱5 小时前
PyTorch深度学习框架60天进阶学习计划 - 第41天:生成对抗网络进阶(三)
人工智能·pytorch·python·深度学习·学习·生成对抗网络
workworkwork勤劳又勇敢5 小时前
Adversarial Attack对抗攻击--李宏毅机器学习笔记
人工智能·笔记·深度学习·机器学习
寻丶幽风6 小时前
论文阅读笔记——Generating Long Sequences with Sparse Transformers
论文阅读·笔记·语言模型·transformer·稀疏自注意力
Angindem6 小时前
websoket 学习笔记
笔记·学习
LVerrrr6 小时前
Missashe考研日记-day18
学习·考研
AI绘画咪酱6 小时前
【CSDN首发】Stable Diffusion从零到精通学习路线分享
人工智能·学习·macos·ai作画·stable diffusion·aigc