编程基础(五)—— 虚拟内存

OSTEP Note: Ch13-23, Memory Virtualization 这是OSTEP 第二部分的阅读笔记,之前的笔记见 OSTEP Note: Ch2-10, Intro & CPU Virtualization 这一部分介绍了OS如何给每个process提供拥有private memory的vision,从base and bound 的方法到segmentation再讲到最终paging。 Memory Virtualization The Abstraction: Address Space Address Space: abstraction of phy 阅读详情

目录

一、概述

二、虚拟内存的出现

三、虚拟内存发展和演进

3.1  Dynamic Relocation (base and bounds)

3.2 segmentation

3.3 paging

3.3.1 第一种优化——TLB

3.3.2 第二种优化——多级页表

四、参考


一、概述

OSTEP memory virtualization相关章节笔记,主要为了理清虚拟内存的为什么是现在这样,备忘。

二、虚拟内存的出现

  1. 起初,OS和一个程序分别放置在物理内存中,OS提供访问资源的接口。
  2. 由于机器价格昂贵,人们希望共享机器资源以节约成本,一个要求是计算机能运行多个程序,多道程序(multiprogramming)在这个时期出现,我们知道,进程等待I/O很耗时,如果在进程等待I/O时机将cpu切换出去运行另一个进程,避免了等待的同时也提高了cpu的使用率。
  3. 之后,随着对计算机更多的要求出现了time sharing,其针对多个交互式用户产生,基本原理是,每个用户运行一段时间,在这个时间内拥有计算机的全部资源,运行一段时间后进行switch,使其他进程运行。
  4. time sharing要实现对资源的完全控制,如在进程运行时是拥有整个物理内存的。实现time sharing的一种方法是运行一段时间后,将内存内容全部保存到磁盘上,当再次轮到自己,再将内存的内容从磁盘恢复到内存中。 这个实现方法简单,但是效率很低——保存整个内存的内容是非常耗时的,远远不如保存通用寄存器和PC那样快——这是不可接受的。因此希望再进程切换时不要将内存全部都保存到磁盘上而是保留再内存中。
  5. 当然4中的方法就做不到完全进程在其运行的过程中完全拥有内存了。做不到资源隔离的后果很严重,试想一个进程运行中修改了其他进程的数据,会造成很严重的后果!
  6. 当然,5中的保护问题可以通过标识访问权限的机制解决,但多个进程同时在物理空间中还会有加载和重定位等难题。对这个问题一个比较好的解决方法是引入地址空间(address space)的概念,地址空间是以进程的角度来看系统中的内存。在地址空间有code,heap,stack。在地址空间的基础上引入内存的虚拟化,如果进程对系统内存的角度(进程地址空间)是一致的,我们只需要建立物理地址空间和虚拟地址空间的映射就可以了,每个进程看到的地址都是虚拟的,运行中看到的是整个虚拟地址空间。进程对地址的视图一致,也使重定位得以简化。

三、虚拟内存发展和演进

首先要明确,程序的地址都是虚拟地址,我们要做的就是在保证在上述约束条件下,将虚拟地址转化为物理地址,需要考虑以下指标:

  • 透明:进程不感知其看到的内存是假的。
  • 效率:引入该机制对系统负担尽可能小,在可接受的范围内。
  • 保护:protection,进程间的资源隔

为了使虚拟地址转换物理地址更有效率,一般需要硬件的支持,这称为hardware-based address translation,简称address translation。当然,只靠硬件支持还是不够的,还需要OS的配合。

先来看一条指令有关于内存存取的操作:

128: movl 0x0(%ebx), %eax ;load 0+ebx into eax

流水线中相关的步骤是fetch和execution,针对上面的指令,fetch时要先将128这个虚拟地址翻译成对应的物理地址,excution时要将%ebx中的虚拟地址翻译成物理地址。

硬件提供地址翻译的部件称为MMU,位于CPU中。

3.1  Dynamic Relocation (base and bounds)

先来看一种最简单的硬件翻译的方式Dynamic Relocation ,该方法引入base和bound寄存器,分别代表物理地址的基址和允许访问物理地址的范围。

硬件通过下面的方式进行翻译:

  • PhyAddr = base + VirtAddr

如果PhyAddr的值超过了bound,那么硬件raise exception,产生protection fault

通过上面的流程总结一下硬件提供的功能:

MMU {

    base

    bound                            //提供base和bound寄存器

    SetBase/SetBound       //提供设置base和bound寄存器的方法。必须在privileged mode下

    RaiseExceptioin            //提供产生异常的能力,如protection fault

    AddressTranlation        //提供将虚拟地址转换为物理地址的能力

}

OS需要配合硬件实现地址转换而实现的功能有:

  • 物理内存管理(Memory management):当一个进程运行时,要为其分配物理地址,OS要对系统的物理内存进行管理(freelist),如在进程初始化时分配一个物理地址。在进程结束时要回收分配的物理地址
  • 在进行context switch时要增加额外的流程:在目前的情况下要将base/bound save到PCB中,新进程根据PCB restore base/bound寄存器——每个进程的base/bound寄存器都是不同的,这样才能隔离资源
  • Exception handling:必须能够处理MMU RaiseException

下面的时序图很好的说明了这个过程:

   

3.2 segmentation

Dynamic  Relocation的方法可以满足2.1中7对应的要求,但是也有它的问题:程序可能只使用很少的空间,但是Dynamic Relocation每次需要分配的物理地址大小是整个进程地址空间大小,这显然会造成地址浪费——Dynamic Relocation会导致内部碎片(internal fragmentation)。

我们可以使用分段来解决这个问题。假设使用三个段(code, heap, stack)对应一个进程,那么可以根据实际使用的情况,大大减少实际分配的内存,实现的方法可以从base-and-bounds改进——可以实现多个base/bound。这时候需要区分地址属于哪个段,所以地址使用逻辑地址即段:偏移的形式使用下面的逻辑操作:

1 // get top 2 bits of 14-bit VA

2 Segment = (VirtualAddress & SEG_MASK) >> SEG_SHIFT

3 // now get offset

4 Offset = VirtualAddress & OFFSET_MASK

5 if (Offset >= Bounds[Segment])

6       RaiseException(PROTECTION_FAULT)  

7 else

8      PhysAddr = Base[Segment] + Offset

9      Register = AccessMemory(PhysAddr)

分段的特性:、

  • 内存增长的方向不一样(upwards/downwards)
  • 可以为每个段增加R/W权限
  • code sharing (通过设置段属性read-only)、

由此可以推广增加段的个数(fine-grained),使用多个段管理内存需要更多的寄存器。

分段解决了Dynamic  Relocation内存管理内部碎片的问题,但同时也引入的新的问题

  1. 在context switch时,需要save/store段寄存器,段越多开销越大。
  2. 每个进程若干段大小不一致,一个是管理起来很复杂,另一个是可能会产生外部碎片。

3.3 paging

分段仍是一种粗粒度的内存管理方式,除了会产生外部碎片,当一个段很大但是很稀疏的时候,也会产生分配物理空间浪费的情况。那么我们考虑一种更细粒度的管理方式:管理固定大小的小块内存,称为分页。

将物理内存看做固定大小的小块(称为页)的数组,数组的下标称为PFN(page frame number),数组元素大小为一个page,每个物理地址向下面这样:

  •  虚拟地址转换为物理地址就是查找VPN->PFN的映射关系!

存储VPN<->PFN对应关系的表称为页表(page table),页表是以VPN为索引的页表项(page table entry)的数组。一个页表项包含PFN和指示标志。

 

PTE中一般包含几个关键位:

  • present bit  表项不在内存中
  • protect bit   没有置为产生保护异常,不允许访问
  • dirty bit    表项对应的页被修改
  • reference bit (a.k.a. accessed bit) 用于page replacement,页是否被访问过

启用分页访问内存的过程

VPN = (VirtualAddress & VPN_MASK) >> SHIFT           // Extract the VPN from the virtual address

PTEAddr = PTBR + (VPN * sizeof(PTE))                         // Form the address of the page-table entry (PTE)

PTE = AccessMemory(PTEAddr)                                    // Fetch the PTE

if (PTE.Valid == False)                                                    // Check if process can access the page

       RaiseException(SEGMENTATION_FAULT)

else if (CanAccess(PTE.ProtectBits) == False)

        RaiseException(PROTECTION_FAULT)

 else     // Access is OK: form physical address and fetch it

        offset = VirtualAddress & OFFSET_MASK

        PhysAddr = (PTE.PFN << PFN_SHIFT) | offset

        Register = AccessMemory(PhysAddr)

3.3.1 第一种优化——TLB

paging机制也面临自己的问题,第一个问题是访问访问慢,如上面的例子仍需要两次访问内存,为了解决这个问题引入TLB进行加速,TLB是页表的缓存,相当是全相连的cache,其结构示意如下:

VPN     |           PFN         |           other bits

TLB流程如下:

1 VPN = (VirtualAddress & VPN_MASK) >> SHIFT

2 (Success, TlbEntry) = TLB_Lookup(VPN)

3 if (Success == True) // TLB Hit

4        if (CanAccess(TlbEntry.ProtectBits) == True)

5                 Offset = VirtualAddress & OFFSET_MASK

6                 PhysAddr = (TlbEntry.PFN << SHIFT) | Offset

7                 Register = AccessMemory(PhysAddr)

8          else

9                 RaiseException(PROTECTION_FAULT)

10 else      // TLB Miss

11        RaiseException(TLB_MISS)

产生tlb miss后,可能会由硬件或者软件处理,软件处理要注意:

  • trap返回要重新执行产生tlb miss的指令而不是下一条。
  • 注意不要引入无限tlb miss

TLB加速了页表的访问,但同时TLB也引入了新问题:

  1. context switch 时要进行flush操作,因为它存储的映射关系只对本进程有效。这样开销很大,即下一个进程会产生tlb miss,解决办法是引入ASID避免刷新整个tlb
  2. cache replacement

3.3.2 第二种优化——多级页表

paging的第二个问题是页表占据的空间太大了,由于页表是基于进程的,假设在32-bit系统下,页大小为4K,那么有1M个页表项,每个页表项4byte,即每个页表占用4M内存,随着进程的增多占据空间增加,如果是64-bit,会占据更大的空间,这是不可接受的。

解决的方法包括以下几种:

  1. 大页,增加page的大小,那么PTE的数量自然会降低,从而减少页表项的大小。(大页的目的主要还是为了减少TLB miss)大页的使用场景还是收到限制,因为大页会产生内部碎片——很多程序只用物理内存中很少的一部分,会造成大量的浪费。
  2. Hybrid Approach: Paging and Segments
  3. 多级页表(multi-level page table) 多级页表的概念很简单:如果一个PTE不可用,就先不用为其分配内存,这样就节省了空间
    1. 只分配要使用的页表
    2. 每一级的页表放在一个页面中,那么内存管理变得更简单,也可以使表项的分配变得更灵活。(32-bit 系统10|10|12, 64-bit系统 9|9|9|9|12,假设页面大小是4K,想想为什么是这样?)
  4. Inverted Page Tables 不再是每个进程一个page table,只有一个page table管理所有的页面,每个entry指示使用这个page的进程以及和该物理页面进行映射的虚拟页面。

多级页表访问流程:

1 VPN = (VirtualAddress & VPN_MASK) >> SHIFT
2 (Success, TlbEntry) = TLB_Lookup(VPN)
3 if (Success == True) // TLB Hit
4       if (CanAccess(TlbEntry.ProtectBits) == True)
5               Offset = VirtualAddress & OFFSET_MASK
6               PhysAddr = (TlbEntry.PFN << SHIFT) | Offset
7               Register = AccessMemory(PhysAddr)
8 else
9               RaiseException(PROTECTION_FAULT)
10 else // TLB Miss
11        // first, get page directory entry
12        PDIndex = (VPN & PD_MASK) >> PD_SHIFT
13        PDEAddr = PDBR + (PDIndex * sizeof(PDE))
14        PDE = AccessMemory(PDEAddr)
15        if (PDE.Valid == False)
16              RaiseException(SEGMENTATION_FAULT)
17        else
18              // PDE is valid: now fetch PTE from page table
19              PTIndex = (VPN & PT_MASK) >> PT_SHIFT
20              PTEAddr = (PDE.PFN << SHIFT) + (PTIndex * sizeof(PTE))
21             PTE = AccessMemory(PTEAddr)
22             if (PTE.Valid == False)
23                     RaiseException(SEGMENTATION_FAULT)
24              else if (CanAccess(PTE.ProtectBits) == False)
25                     RaiseException(PROTECTION_FAULT)
26              else
27                     TLB_Insert(VPN, PTE.PFN, PTE.ProtectBits)
28                     RetryInstruction()
 

四、参考

【1】OSTEP

 

 

 

 

 

 

操作系统笔记(五)覆盖和交换,虚拟内存 前篇: 笔记(二)操作系统的启动、中断、异常、系统调用 笔记(三)(四)内存层次、地址空间、连续/非连续内存分配Index: 5-1 虚拟内存:起因 5-2 覆盖技术 5-3 交换技术 5-4,5 虚拟内存5-1 虚拟内存:起因内存越来越不够用,理想中的存储器是更大,更快,更便宜的非易失存储器。 为了有效管理物理内存,采用了分段,分页,也许在这个基础上可以达到更大更快的理想情况, 阅读详情

相关推荐

操作系统(五) - 虚拟内存

1、 虚拟内存的起因 1.1 大纲 起因 覆盖技术(早期)/交换技术(早期)/虚存技术 虚拟内存技术:目标/程序局部性原理/基本概念/基本特征/虚拟页式内存管理 1.2起因 经常出现内存不够了。程序规模的增长大于存储器容量的增长。 理想的存储器:更大,更快,更便宜,非易失性存储。 实际的存储器 1.3在计算机系统中,尤其是在多道程序运行的环境中,可能会出现内存不够用的情况,怎么办? 如果程序太大,超过了内存的容量,可以采用 手动的覆盖(overlay) 技术,只把需要的指令和数..

Y_M的博客 969

为什么要有虚拟内存?

保障多Java应用共存时的内存安全(隔离性);简化JVM的内存管理(无需关心物理内存碎片、连续性);支撑高效IO操作(如)和动态内存调整(堆扩容)。理解虚拟内存,能帮助Java开发者更科学地配置JVM参数(如-Xmx设置需考虑虚拟地址空间大小)、排查性能问题(如卡顿可能源于swap频繁),让Java程序在复杂的生产环境中更稳定、高效地运行。

weixin_43521001的博客 799

保姆级教程:用Altium Designer 24从零画一块PCB(附完整库文件与避坑清单)

本文提供了一份详细的Altium Designer 24(AD24)PCB设计教程,从工程创建到最终文件输出,涵盖元件库管理、原理图设计、PCB布局布线等全流程。特别适合初学者,包含STM32最小系统板的实战案例,附完整库文件和避坑清单,帮助用户快速掌握AD24的核心功能与技巧。

weixin_27697385的博客 247

虚拟内存技术的来龙去脉(上)

每个现代计算机系统都配有高速可随机访问存储器,称为主存储器、物理内存或者直接称为内存。内存是用于存放代码和数据的硬件,它是处理器能直接寻址的存储空间,内存由半导体器件制成,特点是存取速率快。程序被执行前需要先将程序放到内存中才能被CPU处理,我们平常使用的程序,如操作系统、办公软件、游戏软件等,通常是安装在硬盘等外存上,软件需要运行时,必须把它们调入内存中运行,才能真正被执行。内存的承载实体通常是随机存取存储器(RAM),CPU可以直接与RAM交换数据。内存管理系统虚拟内存。虚拟内存。.........

li_man_man_man的博客 1290

2025年一篇解决Windows11安装医学图像处理工具-FSL(各种问题解决,过程详细,小白轻松安装)

2025年一篇帮你解决FSl安装所有问题,包括环境安装、使用说明、常见问题,过程简单易懂,小白轻松安装。

weixin_52145255的博客 2517

基于SOCKET的***网络软件的设计与实现

二、基于SOCKET的网络软件的需求。2、概要设计:画出软件系统结构图。3、详细设计:软件的详细设计,如类图、序列图、重要的算法流程图或伪代码,等等。4、实现:软件基本功能相关的截图和关键代码。

Recursions的博客 1371

操作系统:内存管理(一)

随着多道程序系统和时分概念的普及,总有多个进程想再CPU上运行,当CPU在进程之间切换的时候,物理内存该怎么处理呢?进程之间的内存能相互隔离吗?方法一: 当进程切换时,可以将与进程有关的PC计数器,通用寄存器以及内存中的所有内容都拷贝到磁盘中,当下次需要再次运行的时候,再将这些内容拷贝到内存中。 这种方法十分暴力直接,但可惜速度太慢。于是乎有了第二中方法方法二: 通过抽象,让每个进程都有一块地

白云流度的博客 777

​开源大模型实战:GLM-4.1V-Thinking本地部署教程(附API调用代码)

​在AI应用从“能用”向“好用”进阶的当下,​的需求愈发强烈:企业需保障数据安全(如医疗影像、金融报告不外传),开发者追求定制化能力(如微调模型适配垂直场景),科研团队则依赖离线环境处理敏感数据。智谱AI开源的​(10B级参数,支持图像、视频、文档多模态推理)凭借的优势,成为本地部署的热门选择。不过,对于“不想折腾技术”的普通用户或快速验证需求的团队而言,​,无需安装配置,打开即用,堪称“零门槛”体验的捷径。本文将分为两部分:先手把手教你​(适合有技术背景的用户),再对比介绍。

gogoMark的博客 1339

分支限界法|Branch and Bound Method(0-1背包问题)

分支限界法 分支限界法(BB或B&B)是一个离散和组合优化问题的算法设计范式,以及一般的实值的问题。分支限界算法是通过状态空间搜索对候选解进行系统枚举的一种算法。 分支与约束(BB或B&B)算法最早是由A. H. Land 和 A. G. Doig在1960年提出的离散规划算法。它是求解各种优化问题的最优解的一种通用算法,特别适用于离散优化和组合优化。一个分支限界算法由一个...

Lawless 8282

STM32开发笔记85: SX1268驱动程序设计(芯片唤醒)

单片机型号:STM32L053R8T6 本系列开发日志,将详述SX1268驱动程序的整个设计过程,本篇介绍芯片唤醒驱动程序。 一、RxDutyCycle模式 在讲述本篇内容之前,我们先来看一下SX1268的一种模式RxDutyCycle,译为中文为接收占空比模式。其可使用SetRxDutyCycle命令进入RxDutyCycle模式,我们来看一下该命令的详细解释。 该命令具有2个参数,...

snmplink的博客 4064

面向边缘计算的YOLOv12模型剪枝-蒸馏联合优化实战教程**

这套剪枝-蒸馏联合方案的优势在于其系统性和可靠性。它不是单一的技巧,而是一套完整的工程流程,确保了从研发到部署的无缝衔接。

FJN110的博客 158

linux系统编程之基础必备(五):Linux进程地址空间和虚拟内存

一、虚拟内存 先来看一张图(来自《Linux内核完全剖析》),如下: 分段机制:即分成代码段,数据段,堆栈段。每个内存段都与一个特权级相关联,即0~3,0具有最高特权级(内核),3则是最低特权级(用户),每当程序试图访问(权限又分为可读、可写和可执行)一个段时,当前特权级CPL就会与段的特权级进行比较,以确定是否有权限访问。每个特权级都有自己的程序栈,当程序从一个特权级切换到另

Meditation 7811

【异常】Claude Code 400错误(Extra inputs are not permitted)解决方案

摘要:Claude Code 2.0.37+版本因API请求包含未支持的custom.input_examples参数导致400错误,使核心功能失效。解决方案是降级至稳定版v2.0.32:先卸载当前版本(npm uninstall -g @anthropic-ai/claude-code),再安装指定版本(npm install -g @anthropic-ai/claude-code@2.0.32),最后验证请求是否恢复正常。该问题确认在v2.0.32版本不存在。(148字)

奶爸的编程之路,也就一周冷个三天 2036

Linux系统编程之虚拟内存

计算机内存是临时存储数据的地方,它比硬盘快得多,但容量有限。现代操作系统通过虚拟内存技术,使得每个进程都感觉自己独占整个地址空间,这不仅提高了安全性,也简化了内存管理。物理内存:实际安装在计算机上的RAM,它是计算机直接使用的高速存储器,所有正在运行的进程和操作系统内核共享同一块物理内存。相比硬盘等其他存储设备,物理内存提供了极高的读写速度。但受制于硬件限制,物理内存的大小通常是固定的,比如:4GB、8GB或更大。虚拟内存。

hope_wisdom的技术博客 1274

mjlab 入门教程(一)MuJoCo 人形机器人强化学习训练 sim-to-real 部署框架

摘要:mjlab是一个结合IsaacLab API与MuJoCo简洁性的GPU加速机器人仿真框架,专为强化学习和机器人研究设计。它提供快速安装(支持uv、pip、conda和Docker)、核心功能(域随机化、NaN守护、观测历史/延迟、执行器/传感器系统)以及从IsaacLab的迁移指南。相比IsaacLab,mjlab更轻量、启动更快,直接构建在MuJoCo Warp上,避免了Omniverse开销。其哲学强调裸机性能、开发者体验和核心领域专注,适合需要快速迭代和直接MuJoCo控制的用户,而Isaac

2506_90492529的博客 2724

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

C语言之编程基础

一.编程语言 、 二. C语言的地位 、 三.C语言是菜鸟和大神的分水岭 、 三.C语言和C++的关系 、 四.数据在内存中的存储 、 五.载入内存,让程序运行起来 、 六.虚拟内存 、 七. ASCII编码

weixin_46372074的博客 3192

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

GPU虚拟内存管理

摘要:GPU虚拟内存管理通过统一虚拟寻址(UVA)实现CPU和GPU共享地址空间,简化异构计算编程。CUDA统一内存(cudaMallocManaged)进一步提供易用性,支持主机和设备直接访问同一内存。底层采用按需分页机制,通过页错误自动迁移数据,但需注意PCIe带宽限制可能导致的性能瓶颈。在多GPU系统中,NVLink可实现GPU间直接内存访问。该技术虽简化编程,仍需优化数据迁移以提升性能。(149字)

1531

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Assembly语言的虚拟内存

虚拟内存作为操作系统的重要特性,在现代计算机系统中发挥着不可或缺的作用。Assembly语言为开发者提供了一种直接控制内存操作的手段,深刻理解Assembly语言能够帮助程序员更好地掌握虚拟内存的工作原理。在虚拟内存与Assembly语言的结合中,程序员可以通过优化内存访问、合理利用中断处理以及使用适当的寻址模式,来提高程序的性能和安全性。无论是在系统级编程还是应用程序开发中,理解虚拟内存的概念与Assembly语言的实现都能够增进开发者对于计算机操作的理解,最终促使我们编写出更高效、更稳定的程序。

2501_91310470的博客 1554

[笔记]Windows核心编程《十五》在应用程序中使用虚拟内存

文章目录前言一、预定地址空间区域1.1 VirtualAlloc函数二、给区域调拨物理存储器三、同时预定和调拨物理存储器四、何时调拨物理存储器五、撤销调拨物理存储器及释放区域六、改变保护属性七、重置物理存储器的内容 前言 Microsoft Windows 提供三种机制来对内存进行操控: 虚拟内存 最适合用来管理大型对象数组或大型结构数组 内存映射文件 最适合用来管理大型数据六(通常是文件) 堆 最用来适合管理大量的小型对象 一、预定地址空间区域 1.1 VirtualAlloc函数 LPVOID W

二次元怪兽的博客 1118

什么是虚拟内存,为什么要使用虚拟内存,虚拟内存可能比物理内存大吗

是的,虚拟内存的大小可以大于物理内存的大小。实际上,操作系统通常会为每个进程分配一个虚拟地址空间,这个空间可以是几GB甚至是数十GB,具体取决于操作系统架构(32位或64位)和系统的配置。因此,程序的虚拟内存可以远远超过实际可用的物理内存。虚拟内存和物理内存之间的关系是相辅相成的。虚拟内存通过提供一个更大的、抽象的内存空间,使得程序能够在物理内存有限的情况下运行,同时也提高了内存管理的灵活性和安全性。

m0_74343664的博客 1355

Windows核心编程:探索虚拟内存

作者:shenzi链接:http://blog.youkuaiyun.com/shenziWindows核心编程:探索虚拟内存1.系统信息     操作系统中有许多值是由系统所运行的主机决定的,如页面大小和分配粒度等。我们应该在进程初始化时取得这些值,然后在代码中使用它们。GetSystemInfo函数用来取得与主机相关的值:

shenzi的天空 5130

Windows核心编程:在应用程序中使用虚拟内存

Windows核心编程:在应用程序中使用虚拟内存    Microsoft Windows提供以下三种机制来对内存进行操控:虚拟内存:最适合用来管理大型对象数组或大型结构数组。内存映射文件:最适合用来管理大型数据流(通常是文件),以及在同一机器上运行的多个进程之间共享数据。堆:最适合用来管理大量的小型对象。      

shenzi的天空 3518

什么是虚拟内存,为什么要使用虚拟内存,虚拟内存可能比物理内存大吗?

虚拟内存是现代操作系统的一个关键特性,它为应用程序提供了一个大且独立的内存空间,通过将部分内存数据存储到硬盘中,帮助系统更有效地管理内存资源。虚拟内存不仅可以比物理内存大,还可以在提高安全性和稳定性的同时简化编程模型。然而,过度依赖虚拟内存可能导致性能下降,因而需要在性能与内存使用之间取得平衡。

2302_80908313的博客 3285

WINDOWS核心编程--虚拟内存

WINDOWS核心编程--虚拟内存windows内存管理每个进程都被赋予它自己的虚拟地址空间。对于32位进程来说,这个地址空间是4GB,因为32位指针可以拥有从0x00000000至0xFFFFFFFF之间的任何一个值。这是虚拟地址空间,不是物理地址空间。该地址空间只是内存地址的一个范围。在你能够成功地访问数据而不会出现违规访问之前,必须赋予物理存储器,或者将物理存储器映射到各个部分的地址

xuwei2007的专栏 2248
上一篇: 并发 (一)——基本概念
下一篇: DPDK分析——KNI
whenloce
博客等级 码龄17年 106粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值