当前位置: 首页 > news >正文

静态存储区(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权限)

相关文章:

  • 从零手写 RPC-version1
  • docker在windows下wsl存储路径的变更与数据迁移
  • 区块链技术在物联网中的应用:构建可信的智能世界
  • 从白平衡色温坐标系调整的角度消除硬件不一致性引起的偏色问题
  • Godot学习-3D基本环境设置以及3D角色移动
  • 叶面温度传感器选清易高精度电热感应器 叶片温度变送器
  • OpenGL学习笔记(Blinn-Phong、伽马矫正、阴影)
  • 第一章:基于Docker环境快速搭建LangChain框架的智能对话系统:从langchain环境搭建到多轮对话代码实现(大语言模型加载)
  • 【专题刷题】滑动窗口(四):
  • 介绍 IntelliJ IDEA 快捷键操作
  • HCIP-OSPF综合实验
  • 通过智能分块策略、动态分块、多路召回与重排序融合、异构数据关联与溯源提升Ragflow与LangChain提升RAG的召回率
  • 【高频考点精讲】JavaScript中的访问者模式:从AST解析到数据转换的艺术
  • windos端远程控制ubuntu运行脚本程序并转发ubuntu端脚本输出的网页
  • 开发NESMA辅助工具版本之需求匹配
  • 【KWDB 创作者计划】_上位机知识篇---PlatformIO
  • 深入详解Java中的@PostConstruct注解:实现简洁而高效初始化操作
  • 量子计算浪潮下的安全应对之法
  • 一个关于相对速度的假想的故事-7
  • 迅为RK3562开发板ARM四核A53核心板多种系统适配全开源
  • 国家卫健委:坚决反对美国白宫网站翻炒新冠病毒“实验室泄漏”
  • 讲武谈兵|英国公布六代机最新渲染图,但研发面临多重难题
  • 世界地球日丨上海交响乐团牵手上海植物园,为“树”写交响曲
  • 开发国内首个泌尿专科智能体,医生们将临床经验转变为知识图谱
  • 直播中抢镜“甲亢哥”的翁东华卸任了!此前任文和友小龙虾公司董事
  • 大卫·第艾维瑞谈历史学与社会理论②丨马克斯·韦伯与历史学研究