虚拟内存空间

article/2025/9/23 14:50:02

每一个进程都会对应一个虚拟地址空间,32位操作系统会为每个进程分配4G(2的32次方)的虚拟地址空间,而MMU(Memory Management Unit,内存管理单元)负责把这4G虚拟内存映射到实际的物理内存中。这4G空间分为用户空间和内核空间两部分。Windows系统下,用户空间和内核空间以2:2比例划分,Linux系统下用户空间和内核空间以3:1划分。内核空间由所有进程共享,用户空间各自独立,程序是无法直接访问内核空间的。 虚拟地址空间分布如下图所示(以Linux系统为例):
在这里插入图片描述
1.保留区(受保护的地址)

保留区即为受保护的地址,大小为128M,位于虚拟地址空间的最低部分,未赋予物理地址。任何对它的引用都是非法的,用于捕捉使用空指针和小整型值指针引用内存的异常情况。

它并不是一个单一的内存区域,而是对地址空间中受到操作系统保护而禁止用户进程访问的地址区域的总称。大多数操作系统中,极小的地址通常都是不允许访问的,如NULL。C语言将无效指针赋值为0也是出于这种考虑,因为0地址上正常情况下不会存放有效的可访问数据。。

2.代码段

代码段也称正文段或文本段,通常用于存放程序执行代码(即CPU执行的机器指令)。一般C语言执行语句都编译成机器代码保存在代码段。通常代码段是可共享的,因此频繁执行的程序只需要在内存中拥有一份拷贝即可。代码段通常属于只读,以防止其他程序意外地修改其指令(对该段的写操作将导致段错误)。某些架构也允许代码段为可写,即允许修改程序。

3.数据段(.data段)
数据段通常用于存放程序中已初始化的全局变量和静态局部变量。数据段属于静态内存分配(静态存储区),可读可写。由于全局变量未初始化时,其默认值为0,因此值为0的全局变量位于.bss段(不位于数据段)。对于未初始化的局部变量,其值是不可预测的。注意:在代码段和数据段之间还包括其它段:只读数据段和符号段等。

4. .bss段
该段用于存放未初始化的全局变量和静态局部变量,包括值为0的全局变量。 数据段和.bss段又称为全局数据区,前者初始化,后者未初始化。
ELF段包括:代码段、其它段(在.data段和.text段之间,包括只读数据段和符号段等)、.data段(数据段)和.bss段,都属于可执行程序部分。

    BSS是“Block Started bySymbol”的缩写,意为“以符号开始的块”。

BSS是Unix链接器产生的未初始化数据段。其他的段分别是包含程序代码的“text”段和包含已初始化数据的“data”段。BSS段的变量只有名称和大小却没有值。此名后来被许多文件格式使用,包括PE。“以符号开始的块”指的是编译器处理未初始化数据的地方。BSS节不包含任何数据,只是简单的维护开始和结束的地址,以便内存区能在运行时被有效地清零。BSS节在应用程序的二进制映象文件中并不存在。

在采用段式内存管理的架构中(比如intel的80x86系统),bss段(Block Started by Symbolsegment)通常是指用来存放程序中未初始化的全局变量的一块内存区域,一般在初始化时bss段部分将会清零。bss段属于静态内存分配,即程序一开始就将其清零了。

比如,在C语言之类的程序编译完成之后,已初始化的全局变量保存在.data段中,未初始化的全局变量保存在.bss 段中。

text和data段都在可执行文件中(在嵌入式系统里一般是固化在镜像文件中),由系统从可执行文件中加载;而bss段不在可执行文件中,由系统初始化。

5.堆空间
new( )和malloc( )函数分配的空间就属于堆空间。

分配的堆内存是经过字节对齐的空间,以适合原子操作。堆管理器通过链表管理每个申请的内存,由于堆申请和释放是无序的,最终会产生内存碎片。堆内存一般由应用程序分配释放,回收的内存可供重新使用。若程序员不释放,程序结束时操作系统可能会自动回收。

堆的末端由break指针标识,当堆管理器需要更多内存时,可通过系统调用brk()和sbrk()来移动break指针以扩张堆,一般由系统自动调用。

使用堆时经常出现两种问题:1) 释放或改写仍在使用的内存(“内存破坏”);2)未释放不再使用的内存(“内存泄漏”)。当释放次数少于申请次数时,可能已造成内存泄漏。泄漏的内存往往比忘记释放的数据结构更大,因为所分配的内存通常会圆整为下个大于申请数量的2的幂次(如申请212B,会圆整为256B)。

    注意,堆不同于数据结构中的”堆”,其行为类似链表。

6.内存映射段(共享库)
内核将硬盘文件的内容直接映射到内存, 任何应用程序都可通过Linux的mmap()系统调用请求这种映射。内存映射是一种方便高效的文件I/O方式, 因而被用于装载动态共享库。如C标准库函数(fread、fwrite、fopen等)和Linux系统I/O函数,它们都是动态库函数,其中C标准库函数都被封装在了/lib/libc.so库文件中,都是二进制文件。这些动态库函数都是与位置无关的代码,即每次被加载进入内存映射区时的位置都是不一样的,因此使用的是其本身的逻辑地址,经过变换成线性地址(虚拟地址),然后再映射到内存。而静态库不一样,由于静态库被链接到可执行文件中,因此其位于代码段,每次在地址空间中的位置都是固定的。

7.栈空间
用于存放局部变量(非静态局部变量,C语言称为自动变量),分配存储空间时从上往下。

【扩展阅读】栈和堆的区别1.管理方式:栈由编译器自动管理;堆由程序员控制,使用方便,但易产生内存泄露。2.生长方向:栈向低地址扩展(即”向下生长”),是连续的内存区域;堆向高地址扩展(即”向上生长”),
是不连续的内存区域。这是由于系统用链表来存储空闲内存地址,自然不连续,而链表从低地址向高地址遍历。3.空间大小:栈顶地址和栈的最大容量由系统预先规定(通常默认2M或10M);
堆的大小则受限于计算机系统中有效的虚拟内存,32位Linux系统中堆内存可达2.9G空间。4.存储内容:栈在函数调用时,首先压入主调函数中下条指令(函数调用语句的下条可执行语句)的地址,
然后是函数实参,然后是被调函数的局部变量。本次调用结束后,局部变量先出栈,
然后是参数,最后栈顶指针指向最开始存的指令地址,程序由该点继续运行下条可执行语句。
堆通常在头部用一个字节存放其大小,堆用于存储生存期与函数调用无关的数据,具体内容由程序员安排。5.分配方式:栈可静态分配或动态分配。静态分配由编译器完成,如局部变量的分配。
动态分配由alloca函数在栈上申请空间,用完后自动释放。堆只能动态分配且手工释放。6.分配效率:栈由计算机底层提供支持:分配专门的寄存器存放栈地址,压栈出栈由专门的指令执行,
因此效率较高。堆由函数库提供,机制复杂,效率比栈低得多。
Windows系统中VirtualAlloc可直接在进程地址空间中分配一块内存,快速且灵活。7.分配后系统响应:只要栈剩余空间大于所申请空间,系统将为程序提供内存,否则报告异常提示栈溢出。操作系统为堆维护一个记录空闲内存地址的链表。当系统收到程序的内存分配申请时,会遍历该链表寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点空间分配给程序。若无足够大小的空间(可能由于内存碎片太多),有可能调用系统功能去增加程序数据段的内存空间,以便有机会分到足够大小的内存,然后进行返回。大多数系统会在该内存空间首地址处记录本次分配的内存大小,供后续的释放函数(如free/delete)正确释放本内存空间。此外,由于找到的堆结点大小不一定正好等于申请的大小,系统会自动将多余的部分重新放入空闲链表中。8.碎片问题:栈不会存在碎片问题,因为栈是先进后出的队列,内存块弹出栈之前,在其上面的后进的栈内容已弹出。
而频繁申请释放操作会造成堆内存空间的不连续,从而造成大量碎片,使程序效率降低。可见,堆容易造成内存碎片;由于没有专门的系统支持,效率很低;由于可能引发用户态和内核态切换,内存申请的代价更为昂贵。所以栈在程序中应用最广泛,函数调用也利用栈来完成,调用过程中的参数、返回地址、栈基指针和局部变量等都采用栈的方式存放。所以,建议尽量使用栈,仅在分配大量或大块内存空间时使用堆。使用栈和堆时应避免越界发生,否则可能程序崩溃或破坏程序堆、栈结构,产生意想不到的后果。

8.命令行参数
该段用于存放命令行参数的内容:argc和argv。

9.环境变量
用于存放当前的环境变量,在Linux中用env命令可以查看其值。

10. 内核空间
内核总是驻留在内存中,是操作系统的一部分。内核空间为内核保留,不允许应用程序读写该区域的内容或直接调用内核代码定义的函数。

扩展:一个由c/C++编译的程序占用的内存分为以下几个部分1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。
其操作方式类似于数据结构中的栈。2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。
注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,
初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 
- 程序结束后有系统释放4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放5、程序代码区—存放函数体的二进制代码。

以下两段示例代码:

int a = 0; 全局初始化区char *p1; 全局未初始化区main(){
int b; 栈char s[] = "abc"; 栈char *p2; 栈char *p3 = "123456"; 123456在常量区,p3在栈上。static int c =0; 全局(静态)初始化区p1 = (char *)malloc(10);p2 = (char *)malloc(20);分配得来得10和20字节的区域就在堆区。strcpy(p1, "123456"); 123456放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。}
#include<stdio.h>int a;    //未初始化全局区 .bss
int b=1;    //已初始化全局区  .data
static int c=2;    //已初始化全局区  .data
const int d=3;    //只读数据段,也叫文字常量区 ro.data, d的值不能被修改
int main(void)
{int e=4;    //栈区static int f=5;    //已初始化全局区const int g=6;    //栈区,不能通过变量名修改其值,但可通过其地址修改其值int *p=malloc(sizeof(int))    //指针变量p在栈区,但其所指向的4字节空间在堆区char *str="abcd";    //字符串“abcd”存在文字常量区,指针变量str在栈区,存的是“abcd”的起始地址return 0;
}

参考:
https://www.cnblogs.com/icmzn/p/11824802.html
https://www.cnblogs.com/clover-toeic/p/3754433.html


http://chatgpt.dhexx.cn/article/5DDB0rIb.shtml

相关文章

虚拟化存储和非虚拟化存储

有文件系统的叫虚拟化存储,没有文件系统的叫非虚拟化存储。. 虚拟化存储:由SAN 或 NAS 提供的存储空间,需要添加一层文件系统来屏蔽底层的差异性,性能较差。支持更多的虚拟化特性。 非虚拟化存储:由分布式存储提供的存储空间,没有添加文件系统,性能好,但无法支持高级特…

内存管理:虚拟存储

内存管理——虚拟存储器 目录 内存管理——虚拟存储器虚拟存储器概述常规存储管理方式的特征和局部性原理虚拟存储的定义和特征虚拟存储器的实现方法1.分页请求系统2.请求分段系统 请求分页存储管理方式请求分页中的硬件支持1.请求页表机制2.缺页中断机构3.地址变换机构 请求分…

存储系统 —— 虚拟存储器

本文主要介绍以下几方面的知识&#xff1a; 页式存储器&#xff08;应用于虚拟存储器&#xff09;虚拟存储器&#xff08;深刻理解&#xff09; 1.页式存储器 注&#xff1a; 虚拟地址或虚拟存储器的理解&#xff0c;请参考下文 虚拟存储器 的介绍 页式存储虚地址 VS 实地址 地…

存储虚拟化概述

存储虚拟化概述 一、基本概念 存储虚拟化(Storage Virtualization)最通俗的理解就是对存储硬件资源进行抽象化表现。典型的虚拟化包括如下一些情况&#xff1a;屏蔽系统的复杂性&#xff0c;增加或集成新的功能&#xff0c;仿真、整合或分解现有的服务功能等。虚拟化是作用在一…

虚拟化存储技术

文章目录 前言一、HCLA存储技术趋势与智能存储组件1、HCLA存储技术趋势&#xff08;1&#xff09;、什么是数据存储&#xff08;2&#xff09;、数据存储系统&#xff08;3&#xff09;、数据分类&#xff08;4&#xff09;、数据存储发展趋势小结 2、智能存储组件控制框硬盘框…

【KALI网络安全】DNS攻击(劫持和欺骗)与网络钓鱼的模拟和预防(1)

1、DNS概述 关于DNS的定义&#xff0c;作用&#xff0c;分类以及工作原理&#xff0c;博主已在【Windows Server 2019】DNS服务器的配置与管理——理论】这篇博客中陈述过。 要预防DNS劫持&#xff0c;必须了解它的攻击原理和过程 声明 本博客不是在向大家展示这些攻击的方法…

DNS 欺骗攻击基于ettercap

开启Apache服务器如下图所示 在/var/www/html文件夹下找到index.html 文件用自己新建的文件替换。此为自己新建主页 查看默认主页 本次实验使用kali (192.168.1.88/24) 以及win7系统虚拟机&#xff08;192.168.1.133/24&#xff09; Win7 IP Kali ip 查看ettercap 使用命…

DNS欺骗攻击、DDoS攻击、XSS攻击和SYN Flooding攻击

DNS欺骗攻击 攻击者冒充域名服务器&#xff0c;向目标主机提供错误的DNS信息&#xff0c;当用户尝试浏览网页&#xff0c;输入域名访问某网页&#xff0c;但实际上访问到的IP地址并不是该网页的IP地址&#xff0c;而是攻击者准备的网页的IP地址&#xff0c;所以用户在网页中提…

『网络协议攻防实验』DNS欺骗攻击与防御

前言 靶机&#xff1a;seedubuntu 12.01&#xff0c;IP&#xff1a;192.168.199.138攻击机&#xff1a;Kali-2020.4&#xff0c;IP&#xff1a;192.168.199.129工具&#xff1a;ettercap 原理 DNS&#xff08;DomainNameSystem&#xff0c;域名系统&#xff09;&#xff0c;…

DNS欺骗攻击

1.DNS域名系统&#xff1a;其主要作用是把主机的域名解析IP地址的系统&#xff0c;即使服务器更换了IP地址&#xff0c;我们依旧可以通过域名访问该服务器。 DNS域名查询可以简单的分为五个步骤&#xff1a; 网络用户客户端提出域名转换IP地址的请求地址解析程序resolve生成查…

局域网下ARP欺骗以及DNS劫持

DNS又称为域名劫持 定义&#xff1a; 域名劫持是互联网攻击的一种方式&#xff0c;通过攻击域名解析服务器&#xff08;DNS&#xff09;&#xff0c;或伪造域名解析服务器&#xff08;DNS&#xff09;的方法&#xff0c;把目标网站域名解析到错误的地址从而实现用户无法访问目标…

Seed lab dns欺骗实验——dns localdns remote

文章目录 1. 实验2. 实验步骤及结果2.1 DNS _Local2.1.1 环境搭建容器部署DNS配置测试部署 2.1.2 The Attack TasksTask 1: Directly Spoofing Response to UserTask 2: DNS Cache Poisoning Attack – Spoofing AnswersTask 3: Spoofing NS RecordsTask 4: Spoofing NS Record…

局域网内dns欺骗

今天学习了dns欺骗&#xff0c;对自己的试验结果进行一次记录。 一&#xff1a;对dns文件进行编辑 我们使用的欺骗工具是ettercap&#xff0c;首先对dns的文件进行编辑&#xff0c;通过终端打开 通过 i 键进入编辑状态&#xff0c;然后在红色的矩形中输入&#xff0c;前面的*…

应用“Cain Abel”实现DNS欺骗

环境的搭建&#xff1a; 1&#xff0c;在Windows 7安装IIS服务&#xff0c;访问www.baidu.com或其他任意站点&#xff0c;保存首页文件至本地wwwroot文件夹中&#xff1b; &#xff08;1&#xff09;打开控制面板&#xff0c;找到“程序”&#xff0c;点进去 点击“打开或关闭…

DNS欺骗及防御技术

一、DNS工作原理 1、DNS&#xff1a;域名服务协议&#xff0c;提供主机域名和IP地址之间的转换。 属应用层协议&#xff0c;端口号为53。DNS数据通过无连接的UDP协议传递 2、过程&#xff1a; 被 二、DNS欺骗原理原理及实现 1、DNS欺骗原理 当客户主机向本地DNS服务器查询域名的…

使用kali里的dnschef进行DNS欺骗

1. 前言 DNSChef是针对渗透测试人员和恶意软件分析师的高度可配置的DNS代理。它能够精细配置哪些DNS回复以修改或简单地代理真实响应。为了利用该工具&#xff0c;您必须手动配置DNS服务器以指向DNSChef。 2. 执行参数 选项参数&#xff1a; -h,--help显示帮助信息并退出--f…

DNS欺骗实战

DNS工作过程特点 • DNS 查询请求是层层传递&#xff0c;查询和应答无严格身份验证、会话无加密 • 收到应答后 DNS 服务器会缓存结果 DNS是什么 • DNS(Domain Name System&#xff0c;域名系统)&#xff0c;因特网上作为域名和IP地址相互映射的一个分布式数据库&#xff0c;能…

2.9 ARP和DNS欺骗

1、预备知识&#xff1a;ARP和DNS欺骗原理 1.1ARP欺骗 ARP&#xff08;Address Resolution Protocol&#xff0c;地址解析协议&#xff09;涉及TCP\IP体系结构中网络层的IP地址和数据链路层的MAC地址&#xff0c;即根据IP地址来查询对应的MAC地址。ARP欺骗的实质是破坏IP地址与…

网站被反诈中心DNS劫持解决教程

如果你的网站部分地区用户访问反馈访问不了&#xff0c;测试域名DNS被劫持到了127.0.0.1 或 0.0.0.0 可能是域名被墙了&#xff0c;或则被反诈中心拦截了&#xff0c;如果遇到该问题&#xff0c;需要检测单单被运营商拦截还是也有被反诈中心拦截。 排查过程: 可以把问题域名通过…

投毒、伪装、攻击,DNS 欺骗和钓鱼网站如何一步步诱人掉入陷阱?

【编者按】这篇文章将详细讲解DNS欺骗&#xff08;DNS投毒&#xff09;及钓鱼网站原理知识&#xff0c;并通过Ettercap工具复现某购物网站的钓鱼漏洞&#xff0c;本文的重点是让您对ARP欺骗、DNS欺骗和钓鱼攻击有一定认识。真心希望这篇基础文章对您有所帮助&#xff0c;也欢迎…