您现在的位置是:首页 >技术交流 >Rust in Action笔记 第六章 内存网站首页技术交流

Rust in Action笔记 第六章 内存

Mint2yx4 2024-10-20 00:01:03
简介Rust in Action笔记 第六章 内存
  1. Option<T>类型在Rust中使用了空指针优化(null pointer optimization)来保证该类型在编译后的二进制文件中占用0个字节。None变量是通过一个空指针null pointer来表示;
  2. 内存地址、指针、引用的区别,内存地址是指在内存中的一个字节,由汇编语言提供的一个抽象;指针,有时候也称为裸指针(raw pointer),是指向某种数据类型的内存地址,指针是由高级语言提供的抽象;引用,是一种指针,在动态类型中,引用包含了一个指针以及一些额外的保证,引用是由Rust提供的抽象;
  3. Rust的引用提供了比指针更多的好处:引用永远指向有效的数据;引用的字节排列是紧凑的,有助于CPU快速读取;引用能够提供变长数据类型的长度保证,引用的结构中除了内部指针本身外,还提供一个数据长度的变量,确保程序永远不会跑到内存范围之外;
  4. {:p}可以把变量安装指针的形式打印,打印其内存地址;
  5. 代码列表6.3展示了两种从u8数组转化成字符串的形式,b变量通过String::from_raw_parts(ptr, size, capa)首先把[u8; 10]转化成*const u8然后转化成*mut u8;c变量引入了CStr外部接口,通过CStr::from_ptr(c_ptr)获取一个以结尾的C语言类型的字符串;b和c变量都需要把[u8, n]先转换成*const u8在转换成所需的相应指针类型;
  6. Rust的裸指针分为*const T*mut T,分别是不可变裸指针和可变裸指针,两者之间可以自由转换,Rust的引用&mut T and &T编译出来的结果就成了裸指针,也就是在实际运行过程中不需要通过unsafe也能得到裸指针的性能;
  7. 使用裸指针的原因:不可避免的使用,当需要系统调用OS功能或者某些第三方代码需要裸指针,一般是对C写的一些程序的外部调用;需要多个地方同时访问数据并且对运行时性能要求极高的时候;
  8. C++中的智能指针在Rust中对应的是core::ptr::{Unique, Shared, Weak},胖指针(fat pointer)通常指内存布局,对比瘦指针(thin pointer,通常也指裸指针,只有一个usize宽度),要更大一些,通常有2个usize宽度甚至更多;
  9. core::ptr::Unique是rust中String, Box<T>的构成要素;core::ptr::SharedRc<T>, Arc<T>的构成要素,如果要实现自己的智能指针,可以参考这些智能指针的实现细节;
  10. std::rc::Weak, std::arc::Weak可用于内部互相指向的数据结构,避免循环指针的问题;alloc::raw_vec::RawVec用于实现了Vec<T>, VecDeq<T>,它能够很聪明地给任何类型的数据分配和回收内存;std::cell::UnsafeCell用于实现Cell<T>, RefCell<T>,来提供内部可变性(interior mutability);
  11. "When in doubt, prefer the stack"表示了当不知道把数据放在堆上还是栈上时,优先放在栈上,因为栈比较快,这句话的Rust版本是,When in doulbe, use types that implement Sized,即实现了Sized特征的类型会优先放在栈上存储;
  12. 如何让一个函数同时接受&str, String两种类型的参数,可以使用参数模板<T: AsRef<str>>表示参数T可以称为str的引用,从而调用.as_ref().len()方法,详细可见Page189;
  13. 表6.1给出了简单的栈和堆的对比,注意表中说明了在没有Unsafe的Rust中,使用堆是安全的;
    表6.1
  14. 几个通用的优化堆内存分配的方法:提前分配好足够的空间,将其初始化为0,到使用的时候再将其改为非0值,这种方法比较危险,可能会引发Rust的生命周期检查;自己针对程序设计一个allocator,能更有效地分配出所需的空间;调研使用arena::{Arena, TypedArena},允许对象边创建边使用(created on the fly),arena是一个第三方库,链接
  15. 虚拟内存常用术语,页(Page)、字(Word)、页错误(Page fault)、交换(Swapping)、虚拟内存(Virtual memory)、实际内存(Real memory)、页表(Page table)、段(Segment)、段错误(Segmentation fault)、MMU、TLB(translation lookaside buffer),详见Page203;
  16. 6.4.2节讲了段错误(segmentation fault),当访问一个非法区域时会产生,可以参考下代码实现;
  17. 6.4.3节讲了MMU(memory mamagement unit)的作用,即把虚拟地址翻译成物理地址,以及使用TLB缓存加速的作用, 206页讲了操作系统和CPU在翻译地址过程中用到的一些小tricks;
  18. 下图讲了一个可执行文件(ELF)是如何加载到虚拟内存并运行的过程在这里插入图片描述
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。