欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 金融 > 静态存储区(Static Storage Area)的总结

静态存储区(Static Storage Area)的总结

2025/4/24 13:50:35 来源:https://blog.csdn.net/qq_47355554/article/details/147465325  浏览:    关键词:静态存储区(Static Storage Area)的总结

普通的全局变量未初始化,编译阶段放在com段,链接完后放在bss

在这里插入图片描述

在32位系统中,内核空间为1GB​(地址范围:0xC0000000-0xFFFFFFFF),用户空间为3GB

在这里插入图片描述

高端内存(HIGHMEM)是32位系统访问超过896MB物理内存的解决方案,其虚拟地址范围位于内核空间的最高128MB(0xF8000000-0xFFFFFFFF)

低端内存 lowmem 映射:在 32 - bit Linux 系统中,物理内存的前 896MB 通常被直接映射到内核虚拟地址空间,这样内核可以方便地访问这些内存区域。

在这里插入图片描述

高地址 0xFFFFFFFF
┌──────────────────┐
│    内核空间       │
├──────────────────┤  0xC0000000
│    栈区          │  ↓ 自动增长
├──────────────────┤
│    mmap区域      │  (共享库/匿名映射)
├──────────────────┤
│      堆区        │  ↑ 通过brk扩展
├──────────────────┤
│      .bss        │  未初始化全局变量
├──────────────────┤
│      .data       │  已初始化全局变量
├──────────────────┤
│    .rodata       │  只读数据段
├──────────────────┤
│     .text        │  代码段
└──────────────────┘
低地址 0x00000000

用户空间(3GB)

  • 代码段(.text):0x08048000-0x080xxxxx
  • 数据段:
    ┌─────────────┐
    │.data │ 初始化的全局变量
    │.rodata │ 常量数据
    │.bss │ 未初始化变量
    └─────────────┘
  • 堆区:通过brk扩展,最大可达≈2.9GB
  • mmap区域:动态库/共享内存映射

内核空间(1GB)

  • 低端内存:直接映射物理内存的896MB
  • vmalloc区:0xF0000000-0xFFFEFFFF
  • 高端内存:物理内存>896MB时的映射区
# 查看进程内存映射
cat /proc/$$/maps 
# 查看系统内存布局
dmesg | grep -i "virtual kernel memory layout"

错误位置错误表述正确值
vmalloc区域“120m-8m-8k”32位系统典型范围:0xF0000000-0xFFFEFFFF(约240MB)
栈空间限制“最多能向下拓展8m”默认栈大小8MB(可通过ulimit -s修改)
堆地址范围“堆区能向上拓展将近3g”实际可用堆空间 ≈ 3GB - (text+data+bss+mmap区域)

静态存储区(Static Storage Area)的总结如下:


静态存储区详细总结

1. 内存段划分
内存段存储内容生命周期初始化方式
.text可执行代码(机器指令)程序启动到终止编译器生成
.rodata只读数据(常量字符串、const全局变量)程序启动到终止显式初始化
.data已初始化的全局变量/静态变量(初值非零)程序启动到终止显式初始化
.bss未初始化的全局变量/静态变量(默认初始化为0)程序启动到终止自动零初始化

2. 核心特性对比
特性.text段.rodata段.data段.bss段
可写性❌ 只读❌ 只读✔️ 可写✔️ 可写
磁盘占用✔️ 占用✔️ 占用✔️ 占用❌ 不占用
内存映射方式直接加载直接加载直接加载动态清零
地址增长方向固定地址固定地址固定地址固定地址
优化特性可共享可共享进程私有进程私有

3. 技术细节说明

.text段(代码段)

  • 存储编译后的机器指令
  • 具有 r-x 内存权限(可读、可执行,不可写)
  • 多个进程实例共享同一物理内存(写时复制机制)

.rodata段(只读数据段)

  • 包含字符串常量、const修饰的全局变量
  • 任何写操作会触发段错误(SIGSEGV)
  • 编译器自动将字符串常量放入此段

.data段(已初始化数据)

  • 存放显式初始化的全局/静态变量
  • ELF文件中实际存储初始化值
  • 示例:int global = 10; static int s = 20;

.bss段(未初始化数据)

  • 存放未初始化或初始化为0的全局/静态变量
  • 程序加载时由内核自动填充零值
  • ELF文件仅记录所需空间大小,不占实际磁盘空间

4. 验证方法

查看段信息

# 使用objdump查看段布局
objdump -h program | grep -E '\.text|\.data|\.bss|\.rodata'# 查看运行时内存映射
cat /proc/self/maps

代码验证示例

#include <stdio.h>const int const_val = 10;     // .rodata
int init_val = 20;            // .data
int uninit_val;               // .bssint main() {printf(".text   @ %p\n", main);           // 代码段地址printf(".rodata @ %p\n", "Hello");       // 字符串常量地址printf(".data   @ %p\n", &init_val);     // 已初始化数据地址printf(".bss    @ %p\n", &uninit_val);   // 未初始化数据地址return 0;
}

5. 关键注意事项
  1. 静态变量的初始化

    • C语言规定未初始化的全局/静态变量默认初始化为0
    • C++中类静态成员变量需要单独定义(否则导致链接错误)
  2. 内存权限保护

    • 尝试修改.text.rodata段内容会触发段错误(SIGSEGV)

    • 使用mprotect()可临时修改权限(需root权限)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词