Damian Lau

内存管理

内存管理的三个层面

内存管理方法

内存管理设计目标

32位模式下进程默认内存布局:4GB

 ---------------------------------------------
|--0                                          |
|--128M                                       |
|---------------------------------------------|
|    text segment (ELF): 程序二进制文件       |
|    data segment:用户初始化的静态变量       |
|    bss segment:未初始化静态变量,填充0     |
|---------------------------------------------|
|--random brk offset                          |
|-------------------|                         |
|    heap: grow up                            |
|        ...                                  |
|---------------------------------------------|
|        ...                                  |
|    memory mapping segment: 文件映射grow down|
|-------------------|                         |
|--random mmap offset                         |
|---------------------------------------------|
|        ...                                  |
|    stack: grow down                         |
|-------------------|                         |
|--random stack offset                        |
|---------------------------------------------|
|--3G                                         |
|    kernel space                             |
 ---------------------------------------------

内存相关问题

系统调用通常提供一种最小功能,而库函数通常提供比较复杂的功能。

内核数据结构mm_struct。

段错误

segmentation fault (SIGSEGV)是一个用户态的概念,是操作系统在用户态程序错误访问内存时所做出的处理。

SIGSEGV在很多时候是由于指针越界引起的,但不是所有的指针越界都会引起SIGSEGV,如果不解引用它,是不会发生SIGSEGV的。 而即使解引用了一个越界指针,也不一定会引起SIGSEGV。

几种引起段错误的原因。

错误的访问类型引起

char *s = "hello world";
s[1] = 'E';// SIGSEGV, 常量字符串在最后链接阶段被合并到text segment与代码段合并到一起,处于只读区域

访问不属于进程地址空间的内存

int *p = (int *)0xc0000fff;
*p = 10;// SIGSEGV

访问了不存在的内存

int *a = NULL;
*a = 1;// SIGSEGV

栈溢出/函数返回绝不变量引用

栈溢出/函数返回绝不变量引用,有时SIGSEGV,有时什么也没发生。