3. 内存管理——基础知识

2018-12-18  本文已影响0人  郑行_aover

内存管理和内存分配是操作系统需要重点考虑的问题。以下简单的的写下内存相关的知识。

内存主要分为五个区域:静态区(.data段、.bss段)、文字常量区、代码区(.text)、堆(.heap)、栈(.stack)。

在实际编程中,要时刻注意变量所在的内存区域,以及其生命周期,避免出现内存错误问题。

1. 数据段-.data

数据段属于静态分配内存

——有初值的全局变量、static变量

2. bss段

未初始化的全局变量,或者初始化为0的全局变量,此区域在程序载入时候由内核清0.属于静态分配内存

——未初始化的全局变量

3. 代码段.text

text段在内存中被映射为只读

——可执行代码,字符串常量

4. heap段

动态分配的内存,保存程序的动态变量,堆是先进先出FIFO。

——由malloc、calloc、realloc等函数,手动分配的内存空间

注意:malloc申请的内存不负责初始化,而calloc申请的内存已经初始化为0. realloc可以扩充之前申请的内存。

堆的地址空间向上生长,即堆上保存的数据越多,堆的地址就越高。

5. stack段

栈保存函数的局部变量,参数,以及返回值。是一种后进先出的数据结构。最后放到栈上的数据,将会是最先从栈上移走的数据。

——局部变量、参数、返回值。

栈的生长方向为向下生长,当栈上保存的数据越多,栈的地址就越低。


PS:从存储区域来看:

——寄存器:    速度最快,由编译器来分配。

——堆栈:         堆栈就是栈(stack)。是一种特别快、特别有效的数据保存方式,仅次于寄存器。

——堆:            手动分配固定大小的内存区域,编译器不知道其生命周期和空间大小,更灵活。但是分配存储空间会花掉时间。

从存储方式来看:

——静态存储:数据存活于整个程序的生命周期。全局变量以及static数据

——常量存储:常数值通常置于程序代码内部。这样是十分安全的,因为text段是只读的,所以永远也不会改变。有需要保护的常数,可以将其通过const来修饰。


那么,linux下的虚拟地址空间如何分布?

——只读段:         代码段、rodata段(常量字符串,#define定义的常量)

——数据段:        保存全局变量、静态变量的空间

——堆        :        动态内存,通过malloc、calloc、realloc、new等来分配的内存。堆顶的位置可以通过brk和sbrk进行动态调整

——文件映射区域:    动态库、共享内存等映射物理空间的内存。mmap等函数所分配的虚拟地址空间

——栈        :        用于维护函数调用上下文空间、一般为8M, 可以通过 ulimit -s 查看。    

——内核虚拟空间:用户不可见的内存区域,由内核管理(页表存放在内核空间)    

参看此链接文章——linux环境内存分配原理 mallocinfo

由于虚拟内存的存在,系统整理内存称为可能。即使系统内存整理调整后,虚拟内存的地址不会变,各个线程的栈内存也应该不会发生变化,只是每个内存页对应的物理内存发生变化。

上一篇 下一篇

猜你喜欢

热点阅读