当前位置: 首页 > news >正文

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

📘 目录

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

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

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

struct Connection;

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

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

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

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

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:多个变量想“共同拥有”一个资源?

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

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

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

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 的循环引用?

🌀 什么是循环引用?

a → b → a   // 永远互相指着,永远无法释放

✅ Weak 是什么?

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

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

🔹 borrow_mut 是什么?

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

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> 弱引用。

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

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


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

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离开作用域时自动释放资源自动释放连接、缓存等

相关文章:

  • 丝杆升降机各部件材质深度剖析:解锁高效稳定运行的技术密码
  • Spring Security 中 PasswordEncoder(密码编码器) 及其实现类对比与示例
  • 【深度学习】【目标检测】【Ultralytics-YOLO系列】YOLOV3工程整体结构解析
  • 自动化运行后BeautifulReport内容为空
  • 【第三十一周】ViT 论文阅读笔记
  • 【Redis】redis事物与管道
  • (四)深入理解AVFoundation-播放:高度自定义视频播放器 UI
  • react从零开始的基础课1
  • LeetCode:链表
  • 如何使用DeepSeek制作数学动态可视化课件?
  • MyBatis 中 Mapper 传递参数的多种方法
  • STM32自学进阶指南:从入门到精通的成长路径 | 零基础入门STM32第九十九步
  • 2. Scala 高阶语法之集合与元组
  • 【HarmonyOS 5】鸿蒙实现手写板
  • Linux找不到virtualenvwrapper.sh(已解决)
  • 提示词工程学习笔记
  • FreertosHAL库笔记
  • 什么是供应链金融
  • 监控docker中的java应用
  • python工程中的包管理(requirements.txt)
  • 先去上海后赴北京,苏中城市泰州为何接连拥抱顶流“大城”?
  • 国铁集团去年收入12830亿元增3%,全年铁路运输利润总额创新高
  • 武汉楼市新政:二孩、三孩家庭购买新房可分别享受6万元、12万元购房补贴
  • 水利部将联合最高检开展黄河流域水生态保护专项行动
  • 4月人民币对美元即期汇率微跌,今年以来升值0.48%
  • 外交部:中美双方并未就关税问题进行磋商或谈判