内存管理(一)

内存管理(一) 负责管理系统中的内存空间,并根据进程的需求进行内存分配。内存管理器会记录内存空闲块的信息,以及已分配内存块的使用情况:将逻辑地址(进程中使用的地址)映射到物理地址(实际的内存地址)。地址映射的目的是保护进程的地址空间,防止不同进程之间的地址冲突将逻辑地址转换为物理地址的过程。地址转换通常涉及页表、段表等数据结构的维护和管理,以及地址映射的实现:通过设置内存访问权限(如读、写、执行),保护进程的地址空间不受非法访问或恶意程序的侵害。内存保护可以防止进程之间的相互干扰和非法访问。 阅读详情

一. Windows内存管理体系结构

1.0 进程的虚拟地址空间

     对于32位进程虚拟地址空间大小为4GB,64为16EB(exabytes,百亿字节),每个进程都有自己的私有地址空间,要想正常访问数据需要把物理存储器分配或映射到相应的地址空间。

    说明:在windows中正在运行的线程看不到属于操作系统本身的内存,这意味着它不能无意间访问到操作系统的数据。

1.1 虚拟地址空间的划分

分区

X86 32 windows

X86 32 3G 用户模式

X64 64 windows

Ia64 64 windows

空指针分配

0x00000000

0x00000000

0x00000000'00000000

0x00000000'00000000

0x0000FFFF

0x0000FFFF

0x00000000'0000FFFF

0x00000000'0000FFFF

用户模式

0x00010000

0x00010000

0x00000000'00010000

0x00000000'00010000

0x7FFEFFFF

0xBFFEFFFF

0x000007FF'FFFEFFFF

0x000006FB'FFFEFFFF

64k禁止访问

0x7FFF0000

0xBFFF0000

0x000007FF'FFFF0000

0x000006FB'FFFF0000

0x7FFFFFFF

0xBFFFFFFF

0x000007FF'FFFFFFFF

0x000006FB'FFFFFFFF

内核模式

0x80000000

0xC0000000

0x00000800'00000000

0x000006FC'00000000

0xFFFFFFFF

0xFFFFFFFF

0xFFFFFFFF'FFFFFFFF

 

32和64有同样的分区,不同的是分区尺寸和位置。

     a.空指针分配区域

     这一分区是为了帮助程序员捕获对空指针的赋值,对这一分区的操作将会引发访问违规。

     如:int* pnSomeInteger = (int*) malloc(sizeof(int));

   *pnSomeInteger = 5;

     如果分配函数不能发现足够的内存来满足请求,返回NULL。然而,这个代码没有检查那样一种可能-假设分配成功并且进行访问在地址00000000上的内 存。因为这个地址空间的区域是禁止访问的,内存访问违例发生并且进程被终止。(违例和终止)有助于开发者发现他们程序的bug。注意没有任何办法可以使我们分配到在这个地址范围的虚拟内存即使你使用 win32api。

     b.用户模式分区

这个分区是进程的地址空间驻扎的地方。有用的地址范围和用户模式分区的大致地址依赖于处理器架构,显示在下表:

架构

可用用户模式分区地址范围

可用用户模式分区尺寸

x 86 (普通)

0x00010000 è 0x7FFEFFFF

~2 GB

x 86 w/3 GB

0x00010000 è 0xBFFFFFFF

~3 GB

x 64

0x00000000'00010000 è 0x000007FF'FFFEFFFF

~8192 GB

IA-64

0x00000000'00010000 è 0x000006FB'FFFEFFFF

~7152 GB

   一个进程不能使用指针用任何方式读取写入访问另一个进程的驻扎在这个分区的数据。所有程序,这个分区是进程的大量数据被维护的地方。

      说明: 在windows中,所有的EXE和DLL都会载入到这里的不同地址(虽然可能性很小)。系统同时会把该进程可以访问的所有内存映射文件映射到这一分区。

      进程可用地址空间的量少于总量的一半。内核模式分区需要整个地址空间的上半部分,系统需要这个空间为了内核代码,设备驱动代码,设备输入输出缓存缓冲区,非分页池分配,进程页面表,等待。事实上,微软已经将内核压缩到这2GB空 间中。在64位windows,内核终于得到它真正需要的空间。

     c.在x86windows得到一个更大的用户模式区域

     一些应用程序,诸如微软的sql服务程序,将会从用户模式大于2Gb获得益处为了增强效能和可测量性通过有更多的程序数据可以寻址。所以 x86windows版本提供升级用户模式分区到3G的方式。为了让所有进程使用大于2G用户模式分区和小于1G内核模式分区,你需要对windows中的配置数据(boot configuration data简称BCD)进行设定并且重启机器(详见MSDN)

    一个解决方案允许应用程序工作在一个大的用户模式的地址空间环境。当系统将要运行一个应用程序,它检查看是否应用程序使用了/LARGEANNRESSAWARE开关。如果程序没有使用这个开关,操作系统会保留用户模式分区2GB以上到内核模式开始处。

     注意所有的被内核需要的数据和代码被紧紧的压缩到2G分区。所以减少内核地址空间少于2G减少了线程、栈其他系统能够创造的资源的数量。除外,系统能够使 用最大仅仅64G内存,不象128G最大可用当内核默认的2G被使用的时候。)

    用3GB开关:http://msdn.microsoft.com/en-us/library/ff556232.aspx

    说明:操作系统在创造进程的地址空间时检查可执行文件的这个开关标志。对于动态连接库则被系统忽略。因而动态连接库必须正确编写。

    d.在64位windows在得到2GB用户模式分区

    e.内核模式分区

    驻留在这一分区的任何东西为所有的进程所共有。该分区的所有代码和数据都被保护了起来,如果应用程序试图读取或改写这里的内存地址,会引发访问违规。

   1.2 地址空间的区域

      系统创建进程并赋予它地址空间时,可用地址空间中的大部分都市闲置的(free)或尚未分配的(unallocated),为了使用我们必须调用VirtualAlloc来预订(reserving).当应用程序预订地址空间的时候系统会确保区域的起始地址正好是分配粒度(allocation granularity)的整数倍,不同的CPU平台而有所不同,目前所有的CPU都使用64KB。

    应用程序预订地址空间时会确保区域大小正好是系统页面大小的整数倍,页面是一个内存单元,系统通过它来管理内存。x86和x64使用的页面大小为4KB而IA-64为8KB.

   说明:有时系统会以应用程序的名义来预订地址空间区域(如PEB,TEB)。虽然系统规定应用程序在预订地址空间区域时起始地址必须是分配粒度的整数倍,但系统自己却不存在同样的限制,非常有可能出现系统为PEB,TEB预订的区域地址并非64KB的整数倍。但是这些区域仍然必须是CPU页面大小的整数倍。

   如果应用程序试图预订一块大小为10KB的地址空间区域,那么系统会自动取页面大小的整数倍,这意味着在x86和x64上会预订12KB的区域,在IA-64中16KB.

  当应用程序不在需要预订区域时调用VirtualFree来释放该区域。

  1.3 给区域调拨物理存储器

    为了使用预订的地址空间区域,我们还必须分配物理存储器,并将其映射到所预订的区域。这个过程被称为调拨(committimg)物理存储器。物理存储器始终都以页面为单位来调拨(使用VirtualAlloc).当我们调拨物理存储器给区域时,并不需要给整个区域都调拨。当程序不需要时我们应该撤销调拨(decommitting)物理存储器,通过VirtualFree函数来完成。

  1.4物理存储器和页交换文件

     当应用程序调用VirtualAlloc函数来把物理存储器调拨给地址空间区域时,该空间实际上是从硬盘的页交换文件分配得到的。

     当用户要求执行一个应用程序的时候。系统会打开该应用程序对应的EXE文件并计算出应用程序的代码和数据的大小。然后系统会预订一块地址空间,并注明与该区域相关联的物理存储器就是EXE文件本身。系统并没有从页交换文件中分配空间,而是将EXE文件的实际内容(或文件映像,即file image)用作程序预订的地址空间区域。这样一来,不但载入程序非常快,而且页交换文件也可以保持一个合理的大小。

     当把一个程序位于硬盘上的文件映像(即一个EXE或DLL文件)用作地址空间区域对应的物理存储器时,我们称为这个文件映像为内存映射文件(memory mapped file)。当载入一个EXE或DLL时系统会自动预订地址空间区域并把文件映像映射到该区域。但系统也提供一组函数可以让开发人员把数据文件映射到地址空间。

    windows可以使用多个页交换文件。如果多个页交换文件位于不同的物理硬盘上,那么系统就可以运行的更快,这是因为系统能同时写入多个硬盘。

    说明:当windows从软盘载入EXE或DLL文件时,系统会把整个文件从软盘复制到内存中。此外,系统还会从页交换文件中分配足够的存储空间来存放文件映像。只有当系统需要把一个页面换出内存,而页面又包含该文件映像的一部分时,系统才会写入页交换文件。如果系统的内存负载很轻,那么文件总是从内存中直接运行。Microsoft必须让在软盘上执行的文件以这种方式运行,因为只有这样安装程序才能正常运行。通常,安装程序会从第一张软盘开始运行,然后再换下一张,由于系统已经将文件复制到内存中(并以页交换文件为后备存储器),因而安装不会遇到问题。除非映像文件是用/SWAPRUN:CD或SWAPRUN:NET开关链接的,否则系统不会把位于其他可移动媒介(比如:光盘或网络驱动器)上的映射文件复制到内存中。

    1.5页面保护属性

      windows的数据执行保护(Data Execution Protection,后面简称DEP)特性提供了对一些恶意软件将代码写入到用于数据的内存区域(比如线程栈上)而让应用程序执行恶意代码的防护。如果启用了DEP,那么只有对那些真正需要执行的代码的内存区域,操作系统才会使用PAGE_EXECUTE_*保护属性。如果CPU试图执行某个页面中的代码,而该页又没有PAGE_EXECUTE_*保护属性,那么CPU会抛出访问违规异常。DEP白皮书:http://go.microsoft.com/fwlink/?linkid=28022 。

    1.6 写时复制

    PAGE_WRITECOPY和PAGE_EXECUTE_WRITECOPY属性目的是为了节省内存和页交换文件的使用。windows支持一种机制,允许两个或两个以上的进程共享同一块存储器,这样极大的提升了系统的性能。但如果某一个应用程序修改并写入一个存储页,那么会导致混乱。为了避免此,操作系统会给共享的存储页指定写时复制属性。当系统把一个exe或dll映射到一个地址空间的时候,系统会计算有多少个页面时可写的(代码页面被标记PAGE_EXECUTR_READ,数据页面被标记PAGE_READWRITE )然后系统会从页交换文件中分配存储空间来容纳这些可写页面。除非应用程序真的写入可写页面,否则不会用到页交换文件中的存储器。

    当线程试图写入一个共享页面时,系统会介入并执行下面的操作。

  1.7 数据对齐的重要性。

 

Qt内存管理(一) 半自动内存管理机制 概述 看多了Qt的代码就会发现,很多人的代码里大量使用new,却很少看到delete,以至于我刚学Qt时也养成了这个习惯,在写C++时也不用delete,结果造成很多麻烦。 原因在于Qt采用半自动的内存管理,不像c++那种全需要自己delete堆内存对象。Qt对象继承自QObject, QObject内部有一个list,会保存children,即QObjectList* children;还有... 阅读详情

相关推荐

Delphi 修改内存保护属性.rar

Delphi 修改内存保护属性,包括修改以下信息:基地址、分配地址、区域大孝所分配保护属性、访问的保护属性、内存状态、内存类型等。核心源代码如下:   VirtualQuery(Arrayptr, MemInfo, SizeOf(TMemoryBasicInformation));   ListBox1.Items.Add('基地址: ' IntToHex(Longint(MemInfo.BaseAddress),8));   ListBox1.Items.Add('分配地址: ' IntToHex(Longint(    MemInfo.AllocationBase),8));   ListBox1.Items.Add('区域大小: ' IntToStr(MemInfo.RegionSize) ' bytes');   ListBox1.Items.Add('所分配保护属性: ' DisplayProtections(MemInfo.AllocationProtect));   ListBox1.Items.Add('访问的保护属性: ' DisplayProtections(MemInfo.Protect));   case MemInfo.State of    MEM_COMMIT: ListBox1.Items.Add('内存状态: MEM_COMMIT');    MEM_FREE: ListBox1.Items.Add('内存状态: MEM_FREE');    MEM_RESERVE: ListBox1.Items.Add('内存状态: MEM_RESERVE');   end;   case MemInfo.Type_9 of    MEM_IMAGE: ListBox1.Items.Add('内存类型: MEM_IMAGE');    MEM_MAPPED: ListBox1.Items.Add('内存类型: MEM_MAPPED');    MEM_PRIVATE: ListBox1.Items.Add('内存类型: MEM_PRIVATE');   end;

内存分页保护属性修改

N年前看的郁金香老师的内核驱动开发教程,想起这段代码,作个笔记, 希望以后在arm下可能会用得上 VOID DisableWriteProtect( PULONG pOldAttr) { ULONG uAttr; _asm { push eax; moveax, cr0; movuAttr, eax; andeax, 0FFFEFFFFh; // CR0 16 BIT = 0 ...

jian274622701的博客 1312

x64内存读写驱动

可过tp读写大部分tp游戏

如何在linux系统中修改其他进程的内存,如何在任意进程中修改内存保护属性

最近,我们在进行一项安全研究时,需要在任意进程中修改内存空间的保护标志。起初,我们发现这项任务看起来很简单,但在实际操作中,却发现困难重重,还好这些都不是什么大问题。在解决这些问题的过程中,我们还学到了一些新的东西,主要是关于 Linux 机制和内核开发的。在以下的详解中,我们会介绍我们所采取的三种方法以及每次寻求更好解决方案的原因。背景介绍在现代操作系统中,每个进程都有自己的虚拟地址空间(从虚拟...

weixin_29324401的博客 1884

别再踩坑了!QT5.15.2配置Android开发环境保姆级避坑指南(含Java8、SDK Tools版本选择)

本文提供QT5.15.2配置Android开发环境的详细避坑指南,重点解决版本锁定、SDK工具选择和QtCreator配置等常见问题。通过实测推荐的Java8、Android SDK Tools版本及NDK配置,帮助开发者高效完成环境搭建,避免隐性冲突和配置失败。

weixin_42537919的博客 237

西门子工业物联网云平台 Insights Hub 技术白皮书

Insights Hub是西门子公司推出的工业物联网云平台,它是一个使用开放技术的基于云架构的平台,能够为制造业企业提供物联网连接、数据分析、应用开发等一系列服务。Insights Hub的设计理念是“连接、分析和运营”,即通过连接物理设备、收集数据并进行分析,来优化工业生产的运营和管理。

可爱的刘三岁的博客 3333

Windows Shellcode学习笔记——通过VirtualProtect绕过DEP

本文讲的是Windows Shellcode学习笔记——通过VirtualProtect绕过DEP, 0x00 前言 在掌握了栈溢出的基本原理和利用方法后,接下来就要研究如何绕过Windows系统对栈溢出利用的重重防护,所以测试环境也从xp转到了Win7(相比xp,Win7的防护更全面)。本文将要介绍经典的DEP绕过方法——通过VirtualProte...

weixin_34004576的博客 2026

告别谷歌翻译失效!手把手教你用Immersive Translate插件实现双语网页阅读(附Chrome/Edge/Firefox保姆级配置)

本文详细介绍了如何使用Immersive Translate插件实现双语网页阅读,解决谷歌翻译失效的问题。通过Chrome、Edge和Firefox的保姆级配置指南,帮助用户轻松安装和使用这款支持双语对照、智能识别网页内容的翻译插件,提升外文资料阅读效率。

weixin_28683689的博客 485

第7章 处理器体系架构详解

本章详细解析x86-64处理器体系架构,重点介绍三种运行模式:实模式(16位)、保护模式(32位)和IA-32e模式(64位)。处理器通过寄存器扩展(从16位到64位)和新增指令集(如CPUID)不断演进,为操作系统提供内存保护、特权级隔离等关键功能。64位模式通过增加寄存器数量、简化段机制等改进大幅提升性能。操作系统利用这些硬件特性实现进程隔离、内存管理等核心功能,处理器架构的进步直接推动了操作系统的发展。

小宝哥Code的专栏 571

【feature_column处理】- indicator_column(指示列)和embedding_column(嵌入列)

1. 开胃菜 我们先来了解一下tf.feature_column.input_layer def input_layer(features, feature_columns, weight_collections=None, trainable=True, cols_to_vars=None, cols_to_output_tensors=None)

DataAlgo 1485

fins协议握手信号服务器响应,欧姆龙FinsTCP与FinsUDP协议解析 —— 利用Wireshark对报文逐字节进行解析详细解析附含报文模拟器等...

前言 – Fins欧姆龙这个协议网上极少有相关的模拟器、Tcp的这一块倒是有但是Udp的基本都是不可用1、 Fins协议结构也很简单 协议分为两种 一种tcp一种udp2、 Tcp比Udp的报文会多一层tcp的head头部3、 Udp回应报文在Wireshark中是解析不到(因为他按照UDP的格式去解那指定是解不到)好长时间没有更新过博客了、也比较懒= = 。一、Read(TCP)发包那么这个就很...

weixin_32491317的博客 4437

Hook技术:虚表hook及虚函数的调用过程详解(附源码)

偶然间看到一篇帖子讲述的是虚表Hook,之前没有接触过,兴趣多致,进行学习和实践,将个人感悟与代码分享出来。 什么是虚表hook? 首先我们应该要先了解什么是虚表? 虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table。 在这个表中,主是要一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其容真实反应实际的函数。 我们调...

weixin_43742894的博客 2957

【Out-of-Distribution Detection】Evidential Deep Learning in NeurIPS 2018 个人理解

核心思想是将分类器的概率输出视为一个狄利克雷分布(Dirichlet Distribution)并替换,之后引入两个损失分别负责保证预测结果准确性和提升被错误分类的样本的不确定性。

研究兴趣:开放集识别、开放世界识别、新类发现、增量学习、少样本学习 2434

【Python面试①】——Python如何进行内存管理

Python如何进行内存管理,采用引用计数机制为主,标记-清除和分代收集(隔代回收)两种机制为辅的策略

Python全栈系列 4948

【Mode】微带传输线阻抗

微带线,英文名称为 (Microstrip) 是一种常见的平面传输线,主要用于传输微波频率信号(通常在射频和微波电路重中使用)。

u011699626的博客 243

MediaPipe 从入门到精通:安装、配置与多场景应用实战手册

人体姿态检测是 MediaPipe 的核心功能之一,它能够从图像或视频中识别人体姿态,并输出关键点的坐标。这些关键点覆盖了身体的主要部位,例如肩膀、肘部、髋部、膝盖等,总计 33 个点。每个关键点包含 x、y、z 坐标(归一化到 0-1 范围)以及可见性评分,可用于分析动作、姿势或开发健身、游戏等应用。手部关键点检测是 MediaPipe 的另一大亮点,它可以识别图像或视频中的手部,并输出 21 个关键点的坐标。这些关键点覆盖手掌和手指的各个部位,适用于手势识别、虚拟现实或交互式应用。

m0_71589036的博客 389

内存管理笔记一、内存管理的需求

内存管理笔记一、内存管理的需求 引言:清楚内存管理需求,会帮助我们更好的学习和理解内存管理相关的机制和策略。 内存管理笔记一、内存管理的需求 重定位: 保护: 共享: 逻辑组织: 物理组织:    在单道程序设计系统中,内存被划分成两部分:一部分供操作系统使用(驻留监控程序、内核),一部分供当前正在执行的程序使用。在多道程序设计系统中,必须在内存中进一步细分出“...

邓博学习笔记 1671

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

linux内存管理 一,Linux内存管理(一)

经过长时间的学习Linux内存管理,在此拿出来和大家分享一下,看完本文你肯定有不少收获,希望本文能教会你更多东西。比如Linux能够使用文件系统中的一个常规文件或一个独立的分区作为交换空间。交换分区要快一些,但是很容易改变交换文件的大小(也就无需重分区整个硬盘,并且可以从临时分区中安装任何东西)。Linux内存管理“Minnet、jag、har、tappat、mitt、minne、jag、sven...

weixin_29705519的博客 99

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

linux内存管理(一)-内存管理架构

内存管理架构 内存管理子系统架构可以分为:用户空间、内核空间及硬件部分3个层面,具体结构如下所示: 1、用户空间:应用程序使用malloc()申请内存资源/free()释放内存资源。 2、内核空间:内核总是驻留在内存中,是操作系统的一部分。内核空间为内核保留,不允许应用程序读写该区域的内容或直接调用内核代码定义的函数。 3、硬件:处理器包含一个内存管理单元(Memory Management Uint,MMU)的部件,负责把虚拟地址转换为物理地址。 2.虚拟地址空间布局架构 上面的用户空间和内核空间所指的都

jianjian的博客 4782

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Java内存管理(一)

Java相比传统语言(C,C++)的一个优势在于其能够自动管理内存,从而将开发者管理内存任务剥离开来。 本文大体描述了J2SE 5.0 release中JVM对于内存是如何管理的。并且为选择和配置对应的收集器,配置收集器的参数提供了一些建议和参考。手动VS自动内存管理内存管理是能够识别哪些释放的对象不再使用,释放掉这些对象所占用空间的一个

EthanPark的博客 3628

一张图掌握Glide内存管理

Glide源码异常庞大, 其中的代码是非常复杂的, 所以笔者不会逐行的分析源码,避免读者陷入代码黑洞中无法自拔,而是通过分析关键的代码和流程来让读者快速的理解和掌握Glide内存管理策略的核心思想。

Gaga246的博客 1360

Linux 内存管理一

疫情在家,整理下以前的学习笔记, 作为linux 三个最重要的部分之一(进程,io,内存),内存管理是非常重要的,是深入理解linux各个部分的基础,linux的内存管理与其他rtos的内存管理不一样,他是一个“富” os,也就是支持很多的应用同时跑,还需要支持应用之间的内存隔离。Linux 内存不仅仅用于内存,比如作为硬盘的补充,硬盘本身也可以作为内存来使用。 硬件原理和分页管理 ...

mj5742356的专栏 635

聊一聊内存管理(一)

欢迎点击「算法与编程之美」↑关注我们!本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章。“最近的电脑打开程序非常慢,而且运行的时候很卡,有没有什...

算法与编程之美 489
上一篇: 结构化异常
下一篇: 内存管理(二)
SWenJing
博客等级 码龄18年 8粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值