阅读 73

有关内存管理的一些知识

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

内存管理

内存管理是指软件运行时对资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。一个堆栈在执行的时候,占用的内存的虚拟地址空间一般被分为几个区域,称之为“段”。常见的有代码段bss段数据段函数调用栈以及

其中与程序执行最相关的有堆和栈(函数调用栈)。堆内存是存储一些复杂数据所用的内存,而栈上一般存放的是函数的作用域以及简单类型的变量。每个线程都会有一个栈,而每个应用程序通常只有一个堆。

堆和栈的主要区别

  • 栈上保存的局部变量在退出所在的作用域时会自动释放
  • 堆上分配·的内存需要主动释放,并且没有作用域
  • 栈上的内存在编译时间可以确定(一般情况下)
  • 栈有一定的长度限制,超出会溢出

segfault

segfault是“segmentation fault”的缩写形式,可以翻译为“段错误”。在进程空间中每个段通过硬件MMU映射到真正的物理空间,在这个过错中,可以给不同的段设置不同的权限,如果程序运行过程中违反了某条权限,CPU会产生一个硬件异常,接着被操作系统内核处理,并通知进程,进程被结束。rust在不利用自动垃圾回收机制的情况下,避免了产生segfault错误,而所有权的引入则是rust解决这类问题的主要方法。

常见的内存不安全

  • 空指针
  • 野指针
  • 悬垂指针
  • 使用为初始化的内存
  • 内存的非法释放
  • 缓存溢出
  • 非法函数指针的调用
  • 数据竞争

空指针是对空指针的不安全解引用,从而形成segfault;而野指针是指为初始化的指针,它的值取决于这个位置在之前的使用中遗留的值,有可能指向任意一个地方,同样对它的解引用很有可能造成segfault。悬垂指针就是内存被释放后以后存在的指针,与野指针类似。患有执行非法函数指针,如果一个函数指针不是精确的指向一个函数地址,那调用这个函数指针会导致一段随机数据被当成指令执行,这是非常危险的事。

以上列举出的常见的内存不安全的问题在运行的时候不一定会被系统检测出来,但是一定会造成程序运行结果的bug,这时排解bug是一个比较困难的事。

在rust中有一个重要的概念panic,panic不属于内存安全相关的问题,它与操作系统的core dump有重大区别。panic是发生不可恢复错误后,程序主动执行的错误处理机制,而core dump是程序失控时操作系统强制退出或者结束线程引起的。panic发生的地方就是程序错误的地方,可以通u哦报错信息快速定位,然后修复。panicrust为了防止严重内存安全错误引入的机制。

文章分类
后端
文章标签