读书笔记
🪨《Operatring System:Three Easy Pieces》第十四章 插叙:内存操作API
00 分钟
2022-12-14
2023-8-13
type
status
date
slug
summary
tags
category
icon
password
Property
Aug 13, 2023 04:24 AM
本章介绍unix操作系统的内存分配接口。
👉
关键问题:如何分配和管理内存 在 UNIX/C 程序中,理解如何分配和管理内存是构建健壮和可靠软件的重要基础。通常使用哪些接口?哪些错误需要避免?

内存类型

  • 栈内存
    • 它的申请和释放操作是编译器来隐式管理的,所以有时也称为自动(automatic)内存。比如,一个函数的局部变量,在进入函数时分配,退出时释放。
  • 堆内存
    • 申请和释放都是显式的,比如 C 语言的malloc

库调用

malloc()调用

malloc 的用法,应该都会,不介绍了

free()调用

释放 malloc 分配的空间

calloc()调用

类似 malloc(),返回前会将区域全置 0。

realloc()调用

创建一个更大的内存区域,并将旧区域拷贝到新区域

常见错误

  • 忘记分配内存
  • 没有分配足够的内存
  • 忘记初始化分配的内存
  • 在用完之前释放内存
  • 反复释放内存
  • 错误地调用 free()

系统中的两级内存管理

当你编写一个短时间运行的程序时,可能会使用 malloc()分配一些空间。程序运行并即将完成:是否需要在退出前调用几次 free()?虽然不释放似乎不对,但在真正的意义上,没有任何内存会“丢失”。 原因很简单:系统中实际存在两级内存管理
第一级是由操作系统执行的内存管理,操作系统在进程运行时将内存交给进程,并在进程退出(或以其他方式结束)时将其回收。
第二级管理在每个进程中,例如在调用 malloc()和 free()时,在堆内管理。即使你没有调用 free()(并因此泄露了堆中的内存),操作系统也会在程序结束运行时,收回进程的所有内存(包括用于代码、栈,以及相关堆的内存页)。无论地址空间中堆的状态如何,操作系统都会在进程终止时收回所有这些页面,从而确保即使没有释放内存,也不会丢失内存。

底层操作系统支持

malloc()和 free()不是系统调用,而是库调用
malloc 和 free 依赖于 brk 系统调用,用于改变程序分断(break)位置:堆结束位置。 不应该直接调用 brk 或 sbrk。它们被内存分配库使用。如果你尝试使用它们,很可能会犯一些错。
可以通过 mmap()调用从操作系统获取内存。通过传入正确的参数,mmap()可以在程序中创建一个匿名(anonymous)内存区域——这个区域不与任何特定文件相关联,而是与交换空间(swap space)相关联,这种内存也可以像堆一样对待并管理。

参考


评论
Loading...