linux proc 堆栈_Linux基础知识(二)

本篇介绍一些Linux的内存管理.

1. 进程的内存空间分配

1.1 进程与程序的区别

(1) 程序是保存在磁盘上的可执行文件

(2) 运行程序时, 需要将可执行文件加载到内存, 形成来进程

(3) 一个程序可以同时对应多个进程

1.2 进程在内存中的布局

ae2a2dd4ea30ef575c11b29728e441b6.png

(1) text段(代码段 code segment/text segment)

- 通常是指用来存放程序执行代码的一块内存区域, 这部分区域的大小在程序运行前就已经确定, 该内存区域通常属于只读.

- 在代码段中, 包含一些只读的常数变量, 例如字符串常量等, 具有常属性且被初始化的全局变量.

(2) data 段(数据段 data segment)

- 通常是指用来存放程序中已初始化的全局变量的一块内存区域, 该内存区域通可读可写.

- 在数据段中, 包含已初始化全局变量, 已初始化全局静态变量, 局部静态变量.

(3) bss 段(bss段 block started by symbol segment)

- 通常是指用来存放程序中未初始化的全局变量的一块内存区域, 该内存区域通可读可写.

- 在bss段中, 包含未已初始化全局变量, 未初始化全局静态变量.

(4) 堆(heap)

- 堆是用于存放进程运行中被动态分配的内存段, 它的大小并不固定, 可动态扩张或缩减.

- 当进程调用malloc等函数分配内存时, 新分配的内存就被动态添加到堆上(堆被扩张).

- 当进程利用free等函数释放内存时, 被释放的内存从堆中被剔除(堆被缩减).

(5) 栈(stack)

- 栈又称堆栈,是用户存放程序临时创建的局部变量, 也就是函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量).

- 除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中

- 由于栈的先进先出(FIFO)特点,所以栈特别方便用来保存/恢复调用现场.

- 可以把堆栈看成一个寄存、交换临时数据的内存区.

b7eb5d28a1c1561001267946f3cb0e35.png

1.3. 进程的获取

(1) 操作系统里每打开一个程序都会创建一个进程ID, 即PID(Process Identification), 可

以使用 getpid() 函数和获取所在的进程 ID.

(2) 当一个进程运行期间, 会在操作系统/proc 目录下自动产生一个以对应进程 ID命名的文件夹,其中maps文件可以查看内存的分布情况.

cat /proc/2831/maps第一列起始地址, 第二列队前面地址可以指向的操作, 第三列该段结束地址.

3. 虚拟地址空间机制

3d3f3f8d0b91e1e3920695697a1dcc11.png

(1) 虚拟地址

- linux 编程的时候使用的地址都是虚拟地址

- 可以将虚拟地址视作房间的号牌, 而物理地址即为房间具体的位置

- 每个进程有独立的 0~3G 的地址空间, 进程间共享同一个内核, 内核使用 3G~4G 的虚拟地址空间

- 每个进程有独立的地址映射表

- linux 内核管理内存时的基本单位是页(page), 32bit 机器上内存叶的大小为 40968 即为4K, 可以使用 getpagesize() 函数可获取 page 的大小

(2) 使用虚拟地址的原因

- 给每个进程一个比实际物理内存更大的地址空间

- 便于内存管理

- 同一个 a.out 运行两次, 其中的变量虚拟地址相同, 但是两个进程不会产生相互干扰, 原因在于使用的是虚拟地址, 并且每个地址的地址映射表不同

4. 内存管理的相关函数

(1) 动态分配内存的函数

STL allocator : 内存分配回收自动管理

C++ : new delete 两个运算符

C : malloc free 两个函数

linux/unix : brk(malloc less than 128K) / mmap(malloc more than128K)

内核态 : get_free_page

(2) mmap 函数的作用

- 动态申请内存

- 映射文件 -> 映射普通文件, 映射显存设备

(3) malloc 函数使用时注意点:

- malloc / free 成对出现

- 未执行 malloc 进程中没有堆区的

- 执行 malloc 后, 系统会最少给当前进程分配 33 page

- 每次 malloc 时, 如果向申请 4 个字节的空间, 实则耗费了 16 个字节的空间其中多出来的 12 个字节用于存储该次 malloc 的附加信息

(4) 段错误的产生

在使用内存过程中不要越界, 如果越界访问可能引起系统问题, 产生段错误, 其产生的原因

- 对内存区域进行没有权限的操作, 比如修改只读区

- 访问未映射的虚拟地址内存空间

char* p=NULL;*p='a';

5.static和const关键字

(1) static 关键字

修饰局部变量 :该局部变量放入数据段, 该局部变量在整个进程中始终有效

修饰全局变量 :该变量还是在数据段里, 该变量在整个进程中始终有效, 该变量的作用域只限于本模块内

修饰函数 :本模块可见

(2) const 修饰指针

- 常量指针

int const *p;

p++ const 修饰*p, 所以*p 不能修改, 但是 p可以修改

- 指针常量

int *const p;

*p++ const 修饰 p, 所以 p 不能修改, 但是*p可以修改

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值