0x00 开篇

关于 trait 的相关文章暂告一段落,本篇文章将向咱们介绍下一个计算机的通用概念——内存。假如你是计算机相关专业的读者或许对内存比较了解,那能够略过本篇文章。

0x01 物理内存与虚拟内存

内存是计算机一个重要的概念,不同的语言对内存的办理不同,有手动办理内存主动办理内存的两种方法,这也就导致不同语言直接的功能不同。早期的计算机程序都是直接跑在物理内存上的,这就要求程序巨细不能超过物理内存的上限。现代计算机为提高CPU运用率、并发履行多个程序、阻隔程序间内存地址、打破物理内存上限,采用虚拟内存机制来运行程序。

物理内存便是咱们常说的内存条。而虚拟内存仅仅是一个概念。关于任何一个程序来说,它包含了程序运行时可用的内存空间总和,包含共享的、非共享的、物理内存中的、存在分页中的等等。简单点说:虚拟内存映射 = 物理空间 + 硬盘空间 + 未运用的映射。

虚拟内存巨细组成的地址空间便是虚拟内存空间,虚拟内存空间是有地址空间的。这就引出另一个概念——虚拟地址空间。虚拟地址空间是线性的,咱们所接触的地址都是虚拟地址。虚拟地址空间又被划分为内核空间用户空间。以 4G 内存为例,在Windows 32位操作体系中默许内核空间和用户空间的份额是1:1(2GB的内核空间,2GB的用户空间),而在32位Linux体系中默许的份额是1:3(1GB的内核空间,3GB的用户空间)寻址范围是 0x00000000 – 0xFFFFFFFF。讲了这么多,下面直接看图吧。

【Rust 中级教程】 07 内存

仔细的读者可能发现了,Windows 的内核空间有 64KB 没有运用。从 0x7FFF0000-0x7FFFFFFF:这个64KB是禁止访问的,由于它挨着内核区域,防止内核区域被覆盖,以损坏内核的正确性和完整性,假如试图改写此区域,会产生异常。

最终咱们以Linux体系为例,看下 Linux 体系下的虚拟地址空间示意图。Linux 对进程地址空间有个标准布局,地址空间中由各个不同的内存段组成,主要的内存段如下:

  • 程序段 (Text Segment):可履行文件代码的内存映射

  • 数据段 (Data Segment):可履行文件的已初始化全局变量的内存映射

  • BSS段 (BSS Segment):未初始化的全局变量或许静态变量(用零页初始化)

  • 堆区 (Heap) : 存储动态内存分配,匿名的内存映射

  • 栈区 (Stack) : 进程用户空间栈,由编译器主动分配开释,寄存函数的参数值、局部变量的值等

  • 映射段(Memory Mapping Segment):任何内存映射文件

图片

0x02 栈内存

假如你了解过数据结构,那你必定听说过“栈”,它具有后进先出的特性。栈内存则拥同栈数据结构一样的特性,支撑入栈和出栈。下图是栈数据结构入栈和出栈的示意图。

【Rust 中级教程】 07 内存

当有数据入栈时,栈顶的地址会变小,反之数据出栈时,栈顶的地址会增大。栈内存的主要作用是在程序运行时保存函数调用所保护的一些信息。有关栈内存相关的常识点,咱们能够经过查找或许其他书本了解下,我就不再展开讲解了。

0x03 堆内存

相同,“堆”也存在于数据结构中,它是一颗完全二叉树(有关数据结构相关的常识,后边也会有一系列的文章,这里不再多余赘述)。咱们主要了解堆内存。堆是一个大块的内存空间,程序请求堆空间时是巨细不一,无序且不接连。这就出现一个怎么办理堆内存的问题。Rust编译器现在自带两个默许分配器:alloc_systemalloc_jemalloc。从 Rust 1.32.0 版别开端,把分配器默许切换为 alloc_system,但开发者仍然能够从 crate 运用到alloc_jemalloc。过去Rust运用alloc_jemalloc,虽然普遍认为alloc_jemalloc的功能比较好,但随着时间发展,状况现已改动。

0x04 堆内存和栈内存的差异

其实物理内存并没有区别堆和栈,堆内存和栈内存只存在于虚拟地址空间中。

  • 生命周期

    在栈内存中保存的数据往往生命周期都比较短。比如某个函数履行完毕后,内存会开释。可是假如想要持久的保存数据,这时候需求运用堆。

  • 是否能够确定数据巨细

在写代码时,假如能够知道某种数据类型的巨细,咱们能够将其分配到栈中,如固定巨细的基本数据类型和固定巨细的数组。可是如 果是动态数组则需求分配到堆内存。

  • 速度

    数据在入栈出栈操作要比在堆上分配内存或许在堆上读取数据的速度快。由于入栈出栈操作,位置总是在栈顶。而在堆上操作时要做许多作业。

开发过程中,咱们只能经过指针来把握已分配的堆内存,假如指针指向的堆内存现已开释,可是指针还没有开释(野指针),这就会对咱们的程序造成严峻的影响。

0x05 小结

本篇文章介绍了许多概念,可是我也仅仅简单写一下,假如你对内存方面的常识比较感兴趣,能够多多查找材料。我相信许多人接触 Rust 是由于许多文章都在说 Rust很安全。那么 Rust 为何安全?Rust 为什么能确保内存安全呢?Rust 是怎么办理内存的?和其它干流语言的差异是什么呢?有关这些疑问,接下来的文章将会悉数给你答案。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。