windows内存管理
一 windows系统的内存管理涉及哪些
1.1 虚拟内存管理机制
- windows操作系统使用虚拟内存技术,将磁盘文件,通过映射对象(存储在物理内存)关联,映射到虚拟内存作为文件试图。即用户操作"虚拟内存中File View Object"-> 物理内存中"File Mapping" -> 磁盘文件。
1.2 分页和分段机制
- windows采用分页机制,将内存划分为固定大写的页面,通过页表来映射虚拟地址和物理地址
- 分段机制是将内存划分为不同大小的段,通过段表来管理。
1.3 内存保护
windows通过硬件机制保护系统内存资源,防止程序对内存的非法访问,确保系统的稳定性和安全性
1.4 高级内存管理
windows还提供内存压缩、内存回收、内存优化等功能
内存压缩可以节省生存空间,内存回收能释放不再使用的内存资源,而内存优化则旨在提高系统性能和响应速度。
二 虚拟内存的实现技术 - 文件映射
2.1 磁盘文件,文件映射对象,文件视图的关系
MSDN - 文件映射

注:
文件映射: 将文件内存(File on Disk)于进程的一部分虚拟地址空间关联。
文件映射对象:调用CreateFileMapping创建文件映射对象,维护磁盘文件和虚拟地址关联。
文件视图: 进程用来访问磁盘文件的虚拟地址空间部分。如果使用指针从文件视图读取和写入文件视图的过程,就像使用动态分配的内存一样。使用文件映射可提高可提高效率,因为文件驻留在磁盘上,但文件视图驻留在内存中。
2.2 应用场景(为什么要用文件映射?)
1)解决大文件频繁读写效率问题
直接加载文件到内存(传统方式)
C++读取txt文件
1 逐行读取
void readTxt(string file)
{ifstream infile; infile.open(file.data()); //将文件流对象与文件连接起来 assert(infile.is_open()); //若失败,则输出错误消息,并终止程序运行 string s;while(getline(infile,s)){cout<<s<<endl;}infile.close(); //关闭文件输入流
}
传统方式,将磁盘文件,加载到内存中,频繁操作磁盘文件。
文件映射方式,将磁盘文件,通过关联到文件映射对象中,读取IO效率更高。减少磁盘文件访问次数。
2) 解决多个进程访问共享磁盘文件场景
多个进程,都可以访问文件映射对象。解决IPC通信,数据复制的开销。
2.3 原理
通过文件映射机制,进程可以通过访问内存的方式直接读写磁盘文件,修改内容后由操作系统自动同步的文件进行更新。使用FlushViewOfFile可刷新缓存区,将映射在虚拟内存当中的数据立即回写到磁盘文件。
过程如下所示:
1. CreateFileMapping创建文件映射对象(内核对象,多进程可访问),关联磁盘文件(文件句柄hFile)
2. MapViewOfFile将文件映射对象,映射到进程虚拟地址
2.4 代码
/*This program demonstrates file mapping, especially how to align aview with the system file allocation granularity.
*/#include <windows.h>
#include <stdio.h>
#include <tchar.h>#define BUFFSIZE 1024 // size of the memory to examine at any one time#define FILE_MAP_START 138240 // starting point within the file of// the data to examine (135K)/* The test file. The code below creates the file and populates it,so there is no need to supply it in advance. */TCHAR * lpcTheFile = TEXT("fmtest.txt"); // the file to be manipulatedint main(void)
{HANDLE hMapFile; // handle for the file's memory-mapped regionHANDLE hFile; // the file handleBOOL bFlag; // a result holderDWORD dBytesWritten; // number of bytes writtenDWORD dwFileSize; // temporary storage for file sizesDWORD dwFileMapSize; // size of the file mappingDWORD dwMapViewSize; // the size of the viewDWORD dwFileMapStart; // where to start the file map viewDWORD dwSysGran; // system allocation granularitySYSTEM_INFO SysInfo; // system information; used to get granularityLPVOID lpMapAddress; // pointer to the base address of the// memory-mapped regionchar * pData; // pointer to the dataint i; // loop counterint iData; // on success contains the first int of dataint iViewDelta; // the offset into the view where the data//shows up// Create the test file. Open it "Create Always" to overwrite any// existing file. The data is re-created belowhFile = CreateFile(lpcTheFile,GENERIC_READ | GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);if (hFile == INVALID_HANDLE_VALUE){_tprintf(TEXT("hFile is NULL\n"));_tprintf(TEXT("Target file is %s\n"),lpcTheFile);return 4;}// Get the system allocation granularity.GetSystemInfo(&SysInfo);dwSysGran = SysInfo.dwAllocationGranularity;// Now calculate a few variables. Calculate the file offsets as// 64-bit values, and then get the low-order 32 bits for the// function calls.// To calculate where to start the file mapping, round down the// offset of the data into the file to the nearest multiple of the// system allocation granularity.dwFileMapStart = (FILE_MAP_START / dwSysGran) * dwSysGran;_tprintf (TEXT("The file map view starts at %ld bytes into the file.\n"),dwFileMapStart);// Calculate the size of the file mapping view.dwMapViewSize = (FILE_MAP_START % dwSysGran) + BUFFSIZE;_tprintf (TEXT("The file map view is %ld bytes large.\n"),dwMapViewSize);// How large will the file mapping object be?dwFileMapSize = FILE_MAP_START + BUFFSIZE;_tprintf (TEXT("The file mapping object is %ld bytes large.\n"),dwFileMapSize);// The data of interest isn't at the beginning of the// view, so determine how far into the view to set the pointer.iViewDelta = FILE_MAP_START - dwFileMapStart;_tprintf (TEXT("The data is %d bytes into the view.\n"),iViewDelta);// Now write a file with data suitable for experimentation. This// provides unique int (4-byte) offsets in the file for easy visual// inspection. Note that this code does not check for storage// medium overflow or other errors, which production code should// do. Because an int is 4 bytes, the value at the pointer to the// data should be one quarter of the desired offset into the filefor (i=0; i<(int)dwSysGran; i++){WriteFile (hFile, &i, sizeof (i), &dBytesWritten, NULL);}// Verify that the correct file size was written.dwFileSize = GetFileSize(hFile, NULL);_tprintf(TEXT("hFile size: %10d\n"), dwFileSize);// Create a file mapping object for the file// Note that it is a good idea to ensure the file size is not zerohMapFile = CreateFileMapping( hFile, // current file handleNULL, // default securityPAGE_READWRITE, // read/write permission0, // size of mapping object, highdwFileMapSize, // size of mapping object, lowNULL); // name of mapping objectif (hMapFile == NULL){_tprintf(TEXT("hMapFile is NULL: last error: %d\n"), GetLastError() );return (2);}// Map the view and test the results.lpMapAddress = MapViewOfFile(hMapFile, // handle to// mapping objectFILE_MAP_ALL_ACCESS, // read/write0, // high-order 32// bits of file// offsetdwFileMapStart, // low-order 32// bits of file// offsetdwMapViewSize); // number of bytes// to mapif (lpMapAddress == NULL){_tprintf(TEXT("lpMapAddress is NULL: last error: %d\n"), GetLastError());return 3;}// Calculate the pointer to the data.pData = (char *) lpMapAddress + iViewDelta;// Extract the data, an int. Cast the pointer pData from a "pointer// to char" to a "pointer to int" to get the whole thingiData = *(int *)pData;_tprintf (TEXT("The value at the pointer is %d,\nwhich %s one quarter of the desired file offset.\n"),iData,iData*4 == FILE_MAP_START ? TEXT("is") : TEXT("is not"));// Close the file mapping object and the open filebFlag = UnmapViewOfFile(lpMapAddress);bFlag = CloseHandle(hMapFile); // close the file mapping objectif(!bFlag){_tprintf(TEXT("\nError %ld occurred closing the mapping object!"),GetLastError());}bFlag = CloseHandle(hFile); // close the file itselfif(!bFlag){_tprintf(TEXT("\nError %ld occurred closing the file!"),GetLastError());}return 0;
}
相关文章:
windows内存管理
一 windows系统的内存管理涉及哪些 1.1 虚拟内存管理机制 windows操作系统使用虚拟内存技术,将磁盘文件,通过映射对象(存储在物理内存)关联,映射到虚拟内存作为文件试图。即用户操作"虚拟内存中File View Objec…...
c++ 将指针转换为 void* 后,转换为怎么判断原指针类型?
当将指针转换为void后,擦除了指针所指向对象的类型信息,因此无法通过void指针来判断原始指针的类型。我这里有一套编程入门教程,不仅包含了详细的视频讲解,项目实战。如果你渴望学习编程,不妨点个关注,给个…...
Swift 属性
属性 一、存储属性1、常量结构体实例的存储属性2、延时加载存储属性3、存储属性和实例变量 二、计算属性1、简化 Setter 声明2、简化 Getter 声明3、只读计算属性 三、属性观察器四、属性包装器1、设置被包装属性的初始值2、从属性包装器中呈现一个值 五、全局变量和局部变量六…...
基于maxkey接入jeecgboot并实现账户同步
1. 注册应用 1.1 在统一认证中心注册第三方应用 1.1.1 填写应用名和登录地址 1.1.2 填写认证地址授权方式和作用域 1.1.3 选择权限范围并提交 1.2 配置访问权限 1.2.1 指定用户组 1.1.2 选择注册的应用 1.1.3 在单点登录认证页面查看添加的应用 1.3 同步一个第三方应用的账号…...
kafka Kerberos集群环境部署验证
背景 公司需要对kafka环境进行安全验证,目前考虑到的方案有Kerberos和SSL和SASL_SSL,最终考虑到安全和功能的丰富度,我们最终选择了SASL_SSL方案。处于知识积累的角度,记录一下kafka keberos安装部署的步骤。 机器规划 目前测试环境公搭建了三台kafka主机服务,现在将详细…...
[C++]debug介绍+debug时如何查看指针指向内存处的值
一、简介 预备工具和知识:使用使用VSCode使用Debug。 本文简介:本文将简要介绍debug中Continue,Step Over,Step Into和Restart的功能。并介绍如何在debug时查看动态内存地址(指针)的值; 二、D…...
AI学习指南数学工具篇-凸优化在支持逻辑回归中的应用
AI学习指南数学工具篇-凸优化在支持逻辑回归中的应用 一、引言 在人工智能领域,逻辑回归是一种常见的分类算法,它通过学习样本数据的特征和标签之间的关系,来进行分类预测。而在逻辑回归算法中,凸优化是一种重要的数学工具&…...
Flutter 中的 AspectRatio 小部件:全面指南
Flutter 中的 AspectRatio 小部件:全面指南 Flutter 是一个流行的跨平台 UI 框架,它提供了丰富的小部件来帮助开发者构建高质量的应用程序。在 Flutter 的小部件库中,AspectRatio 是一个非常有用的小部件,它允许开发者以一种简单…...
应用程序中的会话管理和Cookie安全指南
应用程序中的会话管理和Cookie安全指南 在现代应用程序中,会话管理和Cookie安全是确保用户信息和数据安全的重要组成部分。本文将详细介绍会话管理的最佳实践以及如何通过安全的Cookie设置来保护会话ID的交换。 单点登录(SSO)及会话管理机制…...
备战秋招c++ 【持续更新】
T1 牛牛的快递 原题链接:牛牛的快递_牛客题霸_牛客网 (nowcoder.com) 题目类型:模拟 审题&确定思路: 1、超过1kg和不足1kg有两种不同收费方案 ---- 起步价问题 2、超出部分不足1kg的按1kg计算 ----- 向上取整 3、向上取整的实现思路…...
整数拆分~
way:process //上一个拆出来的数是pre //还剩下rest需要去拆 //返回拆解的方法数 #include<iostream> using namespace std;//上一个拆出来的数是pre //还剩下rest需要去拆 //返回拆解的方法数 int process(int pre, int rest) {if(rest0) return 1;//因为后…...
【Qt Creator】跨平台的C++图形用户界面应用程序开发框架---QT
🍁你好,我是 RO-BERRY 📗 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 目录 1.互联网的核心岗位以及职…...
KingbaseES数据库物理备份还原sys_rman
数据库版本:KingbaseES V008R006C008B0014 简介 sys_rman 是 KingbaseES 数据库中重要的物理备份还原工具,支持不同类型的全量备份、差异备份、增量备份,保证数据库在遇到故障时及时使用 sys_rman 来恢复到数据库先前状态。 文章目录如下 1.…...
【CV】视频图像背景分割MOG2,KNN,GMG
当涉及背景分割器(Background Subtractor)时,Mixture of Gaussians(MOG2)、K-Nearest Neighbors(KNN)和Geometric Multigid(GMG)是常用的算法。它们都用于从视频流中提取…...
使用 Python 简单几步去除 PDF 水印
推荐一个AI网站,免费使用豆包AI模型,快去白嫖👉海鲸AI 在处理 PDF 文件时,水印有时会影响文件的可读性或美观性。幸运的是,Python 提供了多种库来操作 PDF 文件,其中 PyMuPDF(又名 fitz…...
【香橙派 AIpro】OrangePi AIpro :教育、机器人、无人机领域的超级AI大脑,华为昇腾处理器驱动的AI开发板新标杆
【OrangePi AIpro:教育、机器人、无人机领域的超级AI大脑,华为昇腾处理器驱动的AI开发板新标杆】 文章目录 一、开箱与初印象1. 初印象2. 上手开机3. 安装和运行 TightVNC 远程桌面3.1. 安装 TightVNC 服务器3.2. 启动 VNC 服务器3.3. 在 Windows 上使用…...
【Mac】 CleanMyMac X for mac V4.15.2中文修复版安装教程
软件介绍 CleanMyMac X是一款为Mac设计的优秀软件,旨在帮助用户优化其设备的性能并提供清理和维护功能。以下是 CleanMyMac X的一些主要功能和特点: 1.系统性能优化:软件可以扫描和修复潜在的性能问题,包括无效的登录项、大文件…...
单片机通信协议(1):SPI简介
关于SPI SPI(串行外设接口)是板载设备间通信接口之一。它是由摩托罗拉公司(飞思卡尔半导体)推出的。由于其简单性和通用性,它被纳入各种外围设备中,并与飞利浦I2C总线并列。 SPI的三线或四线信号数量比IIC…...
免税商品优选购物商城,基于 SpringBoot+Vue+MySQL 开发的前后端分离的免税商品优选购物商城设计实现
目录 一. 前言 二. 功能模块 2.1. 登录界面 2.2. 管理员功能模块 2.3. 商家功能模块 2.4. 用户前台功能模块 2.5. 用户后台功能模块 三. 部分代码实现 四. 源码下载 一. 前言 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过…...
京准电子、NTP电子时钟系统(网络时钟系统)概述
京准电子、NTP电子时钟系统(网络时钟系统)概述 京准电子、NTP电子时钟系统(网络时钟系统)概述 时钟系统工作原理是由母钟接收GPS/北斗卫星的时间信息,母钟通过串口和NTP以太网接口为其他各系统提供统一的标准时间信号&…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...
[USACO23FEB] Bakery S
题目描述 Bessie 开了一家面包店! 在她的面包店里,Bessie 有一个烤箱,可以在 t C t_C tC 的时间内生产一块饼干或在 t M t_M tM 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC,tM≤109)。由于空间…...
小智AI+MCP
什么是小智AI和MCP 如果还不清楚的先看往期文章 手搓小智AI聊天机器人 MCP 深度解析:AI 的USB接口 如何使用小智MCP 1.刷支持mcp的小智固件 2.下载官方MCP的示例代码 Github:https://github.com/78/mcp-calculator 安这个步骤执行 其中MCP_ENDPOI…...
基于谷歌ADK的 智能产品推荐系统(2): 模块功能详解
在我的上一篇博客:基于谷歌ADK的 智能产品推荐系统(1): 功能简介-CSDN博客 中我们介绍了个性化购物 Agent 项目,该项目展示了一个强大的框架,旨在模拟和实现在线购物环境中的智能导购。它不仅仅是一个简单的聊天机器人,更是一个集…...
SOC-ESP32S3部分:30-I2S音频-麦克风扬声器驱动
飞书文档https://x509p6c8to.feishu.cn/wiki/SKZzwIRH3i7lsckUOlzcuJsdnVf I2S简介 I2S(Inter-Integrated Circuit Sound)是一种用于传输数字音频数据的通信协议,广泛应用于音频设备中。 ESP32-S3 包含 2 个 I2S 外设,通过配置…...
