每个进程都运行在一个属于它自己的内存沙盘中,这个沙盘就是虚拟内存(Virtual Memory)
在Linux系统中,虚拟内存不仅简化了程序的编写,还提高了内存的使用效率
本文将深入探讨Linux进程内存布局,帮助读者理解其工作原理和重要性
一、虚拟内存与物理内存的映射 在编写程序时,我们使用的是虚拟内存布局,它是建立在真实的物理内存之上
虚拟内存一般比物理内存要大,并且每个进程都享有独立的虚拟内存
虚拟内存通过一些内存映射机制,被映射到真实的物理内存
这种机制使得程序能够正常执行,即使只有部分地址空间在物理内存中
虚拟内存的规划之一是将每个程序使用的内存切割成小型的、固定大小的“页”(page)单元
相应地,将RAM划分成一系列与虚存页尺寸相同的页帧
任一时刻,每个程序仅有部分页需要驻留在物理内存页帧中,这些页构成了所谓驻留集(resident set)
程序未使用的页拷贝保存在交换区(swap area)内,这是磁盘空间中的保留区域,作为计算机RAM的补充,仅在需要时才会载入物理内存
虚拟内存到物理内存的映射通过数据结构页表实现,内核为每个进程维护一张页表
页表中的每个条目要么指出一个虚拟页面在RAM中的所在位置,要么表明其当前驻留在磁盘上
若进程试图访问的地址并无页表条目与之对应,那么进程将收到一个SIGSEGV信号
二、Linux进程内存布局详解 在32位的Linux系统中,进程的虚拟地址空间大小为4GB,其中低地址空间的3GB属于用户空间,高地址空间的1GB属于内核空间
在用户空间的3GB中,又划分出多个区域:代码段、数据段、BSS段、堆段、内存映射区和栈段
1.代码段(Text Segment) 代码段具有只读权限,用于存放可执行程序、字符串、只读变量等
例如,定义的const变量、printf函数的格式化字符串等
代码段的主要目的是防止进程通过错误指针意外修改自身指令,确保程序的稳定运行
2.数据段(Data Segment) 数据段具有读写权限,用于存放初始值非0的全局变量、静态变量
这些变量的数据会被存储在磁盘空间中,即存放在可执行文件中
3.BSS段(Block Started by Symbol Segment) BSS段同样具有读写权限,用于存放初始值为0或未初始化的全局变量、静态变量
这块内存会由操作系统初始化为0
在程序启动之前,系统会将这些变量所在的内存区域全部初始化为0,而无需在编译阶段进行
4.堆段(Heap Segment) 堆段是运行时可动态分配的内存段,向上生长,由用户进行申请和释放等管理操作
堆段范围由两个指针进行限制:start_brk指针表示堆段的起始地址,brk指针表示堆段的结束地址
堆段的扩张和收缩实际上都是通过移动brk指针来实现的
当用户申请的内存小于128KB时,malloc会通过brk()从堆上申请内存;当用户申请的内存大于等于128KB时,malloc会通过mmap从内存映射区申请内存
5.内存映射段(Memory-Mapped Segment) 内存映射段也称为文件映射区和匿名映射区,加载的动态库、打开的文件等均映射到该区域
内存映射分为文件映射和匿名映射两种
文件映射将文件映射到进程的虚拟地址空间中,而匿名映射则将物理内存映射到进程的虚拟地址空间,如进程间通信
6.栈段(Stack Segment) 栈段用于存放非静态的局部变量、函数调用过程的栈帧信息等,地址空间向下生长,由编译器自动分配和释放
栈帧中存储了函数的局部变量、实参和返回值
栈的增长是从高地址向低地址增长的,即向堆的方向增长
栈的大小在运行时由内核动态调整,栈动态增长后就
hyper虚拟化软件:重塑计算新境界
Linux进程内存布局全解析
Linux系统下高效复制进程技巧揭秘
揭秘嵌套Hyper技术:重塑新媒体传播格局
Xshell Vim中文输入难题解决方案
Linux系统下Jenkins卸载指南
炫酷来袭!探索Hyper摩托车极速魅力
Linux系统下高效复制进程技巧揭秘
Linux系统下Jenkins卸载指南
Linux系统初学者的设置指南
Linux萌宠企鹅:取名大创意
国家转向Linux:操作系统新变革
Linux桌面优化技巧大揭秘.so
Linux版Chromium:极速浏览新体验,打造高效上网环境
U盘变身神器,电脑店轻松装Linux系统
Linux系统下使用Make命令安装软件的指南
Linux必备:文件操作命令大全概览
Linux系统:深入解析Trace补丁应用
Linux系统下快速下载iptables指南