内存管理与进程映像概述
在操作系统和编程中,内存管理是至关重要的,它直接影响程序的性能和稳定性。以下是用户层和系统层内存管理机制的总结,以及进程映像和虚拟内存的相关概念。
一、内存管理
内存管理的过程可以分为用户层和系统层:
用户层
-
STL (Standard Template Library)
- 自动分配/释放内存:C++中通过STL自动管理内存。
-
C++
- new/delete:C++中的内存分配和释放机制,底层调用C语言的内存管理函数。
-
C
- malloc/free:标准C库中的内存管理函数,调用POSIX或Linux内核函数进行内存分配和释放。
-
POSIX
- brk/sbrk:用于调整数据段的末尾来扩展或缩减堆内存。
-
Linux
- mmap/munmap:用于映射和取消映射虚拟内存地址到物理内存。
系统层
-
Kernel (内核)
- kmalloc/vmalloc:用于在内核中分配和释放内存。
-
驱动
- get_free_page:用于在驱动程序中分配内存页。
二、进程映像
程序存储在磁盘上的可执行文件,当程序执行时,系统将其加载到内存中,形成进程。进程的内存分布情况称为进程映像,从低地址到高地址依次为:
- text (代码段):存储二进制指令和常量数据。
- data (数据段):初始化的全局变量和静态局部变量。
- bss (静态数据段):未初始化的全局变量和静态局部变量,程序运行前自动清零。
- heap (堆):由程序员手动管理的大量数据。
- stack (栈):存储局部变量和块变量。
- environ (环境变量表):存储环境变量,每个进程都有一份,互不影响。
- argv (命令行参数):存储程序运行时的命令行参数。
练习
定义各个内存段的数据,并打印它们的地址,与 /proc/[进程id]/maps
文件中对应的内存记录进行对比。
三、虚拟内存
虚拟内存的关键点:
- 每个进程分配4GB虚拟内存空间。
- 用户只能使用虚拟内存,不能直接访问物理内存。
- 虚拟地址和物理内存之间的映射由操作系统动态维护。
- 虚拟地址与物理内存的映射后才能使用,否则会产生段错误。
- 4GB虚拟地址空间分为用户空间(0-3GB)和内核空间(3-4GB)。
- 用户代码不能直接访问内核空间,需通过系统调用间接访问。
四、映射虚拟内存与物理内存的函数
sbrk 和 brk
- sbrk(intptr_t increment):根据增量调整指针的位置,既可映射也可取消映射。
- brk(void *addr):直接修改指针的位置进行内存映射或取消映射。
mmap 和 munmap
- mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset):映射虚拟内存和物理内存。
- munmap(void *addr, size_t length):取消映射。
总结
- sbrk/brk 通过指针移动实现内存映射和取消映射,属于堆内存。
- mmap/munmap 不维护任何状态,直接映射或取消映射。
- malloc/free 底层调用了
sbrk/brk
或mmap/munmap
。 - 虚拟地址通过映射后才能访问物理内存,系统动态管理映射。
理解内存管理机制对优化和调试程序至关重要,特别是在高性能或资源受限的系统中。