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)相关联,这种内存也可以像堆一样对待并管理。参考
- 作者:GJJ
- 链接:https://blog.gaojj.cn/article/blog-11
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。