浅聊一下 C#程序的 内存映射文件 玩法 - 行业资讯 -

当前位置:首页  >  行业资讯  > 正文

浅聊一下 C#程序的 内存映射文件 玩法

浅聊一下 C#程序的 内存映射文件 玩法
2023-06-13 18:30:54 来源:博客园
一:背景1. 讲故事

前段时间训练营里有朋友问 内存映射文件是怎么玩的?说实话这东西理论我相信很多朋友都知道,就是将文件映射到进程的虚拟地址,说起来很容易,那如何让大家眼见为实呢?可能会难倒很多人,所以这篇我以自己的认知尝试让大家眼见为实。


【资料图】

二:如何眼见为实1. 我想象的文件映射

在任何讨论之前,内存文件映射大概像下面这样,多个进程可以完全View一个文件,也可以 View 文件的一部分到进程的虚拟地址中,画个图大概像下面这样。

但仔细一想,这里还有很多的小细节,比如:

疑问1:到底是映射文件还是映射磁盘的物理地址 ?

疑问2:既然是后备存储,那是不是每次修改虚拟地址都要刷硬盘 ?

疑问3:内存页是4k为一个单位,文件大小不是 4k 整数倍怎么办 ?

这三个疑问我相信很多朋友或多或少都会遇到,这里我简单解答一下,后面再用 windbg 验证。

严格来说是 硬盘物理地址

文件所处的硬盘地址为后备存储这个不假,但这里有个小细节,对虚拟地址的读写涉及到 内存页概念,如果访问的虚拟地址所在的物理地址不在 物理内存中,就会引发缺页中断,操作系统会将 磁盘上的 4k 页粒度灌入到 物理内存中,同样的道理,如果修改了虚拟地址,那么物理内存页就是脏数据,会在后续的某个时刻刷新到 硬盘上,产生磁盘 IO。

总的来说:从磁盘到物理内存(内存条) 之间的内存页的换入换出都是一种按需的 懒加载懒写入行为,稍后我们用 windbg 验证下。

内存的管理采用的是内存页的方式,如果 View 大于 文件Size,那么文件会扩容到 4k 对齐,这样方便对文件追加写入。

综合上面的三点信息,图就可以画的再详细一点了,比如下面这样:

熟悉内存管理的朋友应该知道,我们程序的 exe 和 dll 就是用 内存映射文件的方式加载到虚拟地址中的,所以就拿它开刀吧。

2. 一段测试代码

为了方便演示,上一段简单的的测试代码,观察 ConsoleApp1.exe的映射方式。

static void Main(string[] args)        {            Console.WriteLine($"当前时间:{DateTime.Now}, 程序启动!");            Console.ReadLine();        }

接下来用 windbg 启动 ConsoleApp1.exe两次,结合详细分解图,我们观察下这两个进程的虚拟地址所映射的内存条物理地址是否一致?

实例1
ModLoad: 00007ff6`bfe00000 00007ff6`bfe2a000   apphost.exeModLoad: 00007ff9`b1450000 00007ff9`b1648000   ntdll.dll...0:008> lmvm apphostBrowse full module liststart             end                 module name00007ff6`bfe00000 00007ff6`bfe2a000   apphost  C (private pdb symbols)  c:\mysymbols\apphost.pdb\1643A9EB126F4FE184548E9CC1B740B71\apphost.pdb    Loaded symbol image file: D:\net7\ConsoleApplication1\ConsoleApp1\bin\Debug\net6.0\ConsoleApp1.exe    Image path: apphost.exe    Image name: apphost.exe    ...0:008> ~   0  Id: 232c.4abc Suspend: 1 Teb: 0000000e`7b1a5000 Unfrozen
实例2
ModLoad: 00007ff6`bfe00000 00007ff6`bfe2a000   apphost.exeModLoad: 00007ff9`b1450000 00007ff9`b1648000   ntdll.dll...0:008> ~   0  Id: 60e8.3e3c Suspend: 1 Teb: 000000da`ab498000 Unfrozen   1  Id: 60e8.53b0 Suspend: 1 Teb: 000000da`ab49a000 Unfrozen

这里要提醒一下的是在 Windows 平台上 ConsoleApp1.exe已经成了一个引导程序,通过 lmvm 可以看到它其实是 apphost.exe

两个实例都开起来后,可以看到 apphost.exe在各自进程的虚拟地址都一样,那他们的物理地址是否也一样呢? 要寻找答案,接下来我们到 Windows 内核态去挖一挖。

lkd> !process 0 0 ConsoleApp1.exePROCESS ffff838bd84c9080    SessionId: 8  Cid: 232c    Peb: e7b1a4000  ParentCid: 0b14FreezeCount 2    DirBase: 3468cf000  ObjectTable: ffff938feae02900  HandleCount: 172.    Image: ConsoleApp1.exePROCESS ffff838bef157080    SessionId: 8  Cid: 60e8    Peb: daab497000  ParentCid: 4804FreezeCount 2    DirBase: 3552f3000  ObjectTable: ffff938fe8f7ec40  HandleCount: 166.    Image: ConsoleApp1.exe

从卦中看,Cid: 232c是我们的实例1, Cid: 60e8是我们的实例2,接下来用 windbg 提供的 !vtop 命令观察 apphost.exe 的首地址对应的物理地址。

// ----  实例1 -----lkd> !vtop 3468cf000 00007ff6bfe00000Amd64VtoP: Virt 00007ff6bfe00000, pagedir 00000003468cf000Amd64VtoP: PML4E 00000003468cf7f8Amd64VtoP: PDPE 00000001138dbed0Amd64VtoP: PDE 00000002153dcff8Amd64VtoP: PTE 000000024dadd000Amd64VtoP: Mapped phys 00000002271c2000Virtual address 7ff6bfe00000 translates to physical address 2271c2000.//----  实例2 -----lkd> !vtop 3552f3000 00007ff6bfe00000Amd64VtoP: Virt 00007ff6bfe00000, pagedir 00000003552f3000Amd64VtoP: PML4E 00000003552f37f8Amd64VtoP: PDPE 00000002db7ffed0Amd64VtoP: PDE 0000000208100ff8Amd64VtoP: PTE 000000033de01000Amd64VtoP: Mapped phys 00000002271c2000Virtual address 7ff6bfe00000 translates to physical address 2271c2000.

从卦中看,实例1 和 实例2 的 虚拟地址映射的 物理地址是相同的 2271c2000。这也很好的解释了那张图。

有朋友可能会有疑问,能否看下 2271c2000 这个 物理地址的内容? 这当然是可以的,用 windbg 的 !da就好了。

lkd> !db 2271c2000#2271c2000 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ..............#2271c2010 b8 00 00 00 00 00 00 00-40 00 00 00 00 00 00 00 ........@.......#2271c2020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................#2271c2030 00 00 00 00 00 00 00 00-00 00 00 00 e8 00 00 00 ................#2271c2040 0e 1f ba 0e 00 b4 09 cd-21 b8 01 4c cd 21 54 68 ........!..L.!Th#2271c2050 69 73 20 70 72 6f 67 72-61 6d 20 63 61 6e 6e 6f is program canno#2271c2060 74 20 62 65 20 72 75 6e-20 69 6e 20 44 4f 53 20 t be run in DOS #2271c2070 6d 6f 64 65 2e 0d 0d 0a-24 00 00 00 00 00 00 00 mode....$.......

从卦中看,物理地址上有一段 This program cannot be run in DOS mode,这不就是经典的 PE 文件哈,如果不相信可以用 WinHex 打开 ConsoleApp1.exe即可,截图如下:

最后就是内核中的 内存管理器会将 物理地址 与 磁盘地址 进行打通,实现懒加载和懒写入。

3. 如何自定义实现

Image 虽然是一个快捷的观察内存文件映射方式,那如果自己能实现一个就更有意思了,比如下面对 1.txt进行文件映射,在 C# 中有一个快捷类 MemoryMappedFile实现了 win32api 的封装,参考代码如下:

internal class Program    {        static void Main(string[] args)        {            int capaticy = 1024; //1k            using (var mmf = MemoryMappedFile.CreateFromFile(@"C:\1.txt", FileMode.OpenOrCreate,                                                            "testmapfile",                                                             capaticy,                                                             MemoryMappedFileAccess.ReadWrite))            {                var viewAccessor = mmf.CreateViewAccessor(0, capaticy);                while (true)                {                    Console.WriteLine("请输入你要写入的内容: ");                    string input = Console.ReadLine();                    viewAccessor.WriteArray(0, input.ToArray(), 0, input.Length);                }            }        }    }

接下来用 windbg 附加一下,观察 1.txt 是不是被 MappedFile 上了,同时做的修改有没有更新到物理磁盘上。

0:006> !address  BaseAddr EndAddr+1 RgnSize     Type       State                 Protect             Usage-----------------------------------------------------------------------------------------------...+  31a0000  31a1000     1000 MEM_MAPPED  MEM_COMMIT  PAGE_READWRITE                     MappedFile "\Device\HarddiskVolume3\1.txt"...0:006> du 31a0000031a0000  "helloworld!"

从卦中可以看到,虽然 1.txt 最大的 View 区间是 1k,但提交的内存页还是按照最小粒度 4k 给的。

三:总结

这篇我们就简单的浅聊一下,如果这块是知识盲区的朋友应该会有一点帮助,希望没有带偏大家,更多的细节期待大家挖掘!

标签:

(责任编辑:news01)
广汽埃安副总经理:原来车厂不是为电池厂打工 而是为材料厂打工且还是打长工|环球微头条

广汽埃安副总经理:原来车厂不是为电池厂打工 而是为材料厂打工且还是打长工|环球微头条

广汽埃安新能源汽车股份有限公司副总经理席忠民在世界动力电池大会主题
06-11 08:28:27
焦点短讯!《有利的诈欺》绿叶抢眼,尹博再次伙拍金东旭斗戏

焦点短讯!《有利的诈欺》绿叶抢眼,尹博再次伙拍金东旭斗戏

《有利的诈欺》上周顺利起航,讲述天才少女李露云(千玗嬉饰)被诬蔑杀
06-11 07:45:46
全自动马桶水箱盖怎么打开(马桶水箱盖怎么打开) 观天下

全自动马桶水箱盖怎么打开(马桶水箱盖怎么打开) 观天下

相信大家对全自动马桶水箱盖怎么打开,马桶水箱盖怎么打开的问题都很疑
06-11 06:49:45
12306买卧铺票可以在线选铺了!操作指南出炉:很方便-世界看热讯

12306买卧铺票可以在线选铺了!操作指南出炉:很方便-世界看热讯

12306买卧铺票可以在线选铺了!操作指南出炉:很方便
06-11 06:19:15
国际化、专业化、数字化……这场陆家嘴论坛关注金融开放合作与法治保障

国际化、专业化、数字化……这场陆家嘴论坛关注金融开放合作与法治保障

国际化、专业化、数字化……这场陆家嘴论坛关注金融开放合作与法治保障
06-11 06:19:03
资讯:爸爸去哪儿第三季歌曲_爸爸去哪了第三季

资讯:爸爸去哪儿第三季歌曲_爸爸去哪了第三季

1、《爸爸去哪儿》是湖南卫视从韩国MBC电视台引进的亲子户外真人秀节目
06-11 05:43:03
全球信息:咖啡店评弹返场、多彩手工体验!社区刮起最炫非遗风!

全球信息:咖啡店评弹返场、多彩手工体验!社区刮起最炫非遗风!

咖啡店评弹返场、多彩手工体验!社区刮起最炫非遗风!2023年文化和自然
06-11 05:03:34
长恨歌读后感1000字_长恨歌读后感

长恨歌读后感1000字_长恨歌读后感

1、作为一代文人,白居易可谓是一个成功者。2、他的现实主义的笔,写出
06-11 04:26:18
高考配置用笔漏墨:招标背后可有“猫腻”?|天天看点

高考配置用笔漏墨:招标背后可有“猫腻”?|天天看点

高考配置用笔漏墨:招标背后可有“猫腻”?□许卫兵6月7日,不少河南考
06-11 03:17:55
咔嚓咔嚓……超近距离看秦岭野生大熊猫啃竹笋! 当前聚焦

咔嚓咔嚓……超近距离看秦岭野生大熊猫啃竹笋! 当前聚焦

咔嚓咔嚓……超近距离看秦岭野生大熊猫啃竹笋!近日,在陕西佛坪国家级
06-11 03:00:40
AI前哨 | OpenAI联合创始人Sam Altman:安全性很重要 不会很快有GPT-5 焦点速看

AI前哨 | OpenAI联合创始人Sam Altman:安全性很重要 不会很快有GPT-5 焦点速看

凤凰网科技讯《AI前哨》6月10日消息,在2023北京智源大会上,智源研究
06-11 02:52:39
每日快看:中国特供CPU史低价1399 立减220元

每日快看:中国特供CPU史低价1399 立减220元

在年初,Intel面向中国市场推出了两款特供处理器i5-13490F、i7-13790F
06-11 01:40:53
“五个一工程”获奖话剧《路遥》将于7月初上演于美琪大戏院

“五个一工程”获奖话剧《路遥》将于7月初上演于美琪大戏院

“五个一工程”获奖话剧《路遥》将于7月初上演于美琪大戏院继两年前首
06-11 01:14:50
经济日报刊文:如何看待一线城市的“人口信号”

经济日报刊文:如何看待一线城市的“人口信号”

各地2022年统计公报近期陆续发布,北京、上海、广州、深圳四大一线城市
06-11 00:51:01
七星彩第23066期呼延从杀码分析 焦点讯息

七星彩第23066期呼延从杀码分析 焦点讯息

唯彩看球分享七星彩第23066期呼延从杀码分析,查看专家精选胆码、走势
06-10 23:53:19
焦点快报!铀238裂变方程式(铀238)

焦点快报!铀238裂变方程式(铀238)

来为大家解答以上的问题。铀238裂变方程式,铀238这个很多人还不知道,
06-10 23:07:51
今日快讯:15时官宣!钱天一头号种子出战,单挑早田希娜,携手樊振东抗敌!

今日快讯:15时官宣!钱天一头号种子出战,单挑早田希娜,携手樊振东抗敌!

德班世乒赛结束后,国乒众将们开启了短暂的假期,按照国乒总教练李隼的
06-10 22:41:06
事关猴痘!广东疾控最新提醒_今日热文

事关猴痘!广东疾控最新提醒_今日热文

据北京疾控消息,近日北京市医疗机构报告两例猴痘病毒感染病例,两名病
06-10 22:14:38
电脑中缺失maxnetbackburner.dll文件应该怎么处理 环球速看

电脑中缺失maxnetbackburner.dll文件应该怎么处理 环球速看

maxnetbackburner dll是电脑文件中的dll文件(动态链接库文件)。如果在
06-10 21:54:54
思明区政务服务中心“政务智能办”专区启用

思明区政务服务中心“政务智能办”专区启用

近日,位于思明区政务服务中心三楼的“政务智能办”专区启用。该举措由
06-10 21:31:59
柳岩的衣服真“挤”,一袭抹胸连衣裙高级时髦,大方展现曼妙身姿_环球播资讯

柳岩的衣服真“挤”,一袭抹胸连衣裙高级时髦,大方展现曼妙身姿_环球播资讯

1 6新鲜的东西总是更容易引起我们的注意,所以与众不同的设计才能赢得
06-10 21:27:30
国宝画重点丨上天入海,到处“出差”!这件宝贝可不得了

国宝画重点丨上天入海,到处“出差”!这件宝贝可不得了

2023年6月10日是“文化和自然遗产日”今年的主场城市活动在四川成都举
06-10 20:09:30
pdf转jpg怎么转(pdf转jpg)

pdf转jpg怎么转(pdf转jpg)

来为大家解答以上问题,pdf转jpg怎么转,pdf转jpg很多人还不知道,现在
06-10 18:54:35
回访章莹颖父亲:用余生把女儿带回家 | 面孔 当前热文

回访章莹颖父亲:用余生把女儿带回家 | 面孔 当前热文

章莹颖遇难6年男友至今未婚
06-10 18:49:09
【共同缔造安全江夏⑭】摄影作品:电力阶梯

【共同缔造安全江夏⑭】摄影作品:电力阶梯

【共同缔造安全江夏⑭】摄影作品:电力阶梯---电力工人为了保障江夏区
06-10 18:10:25
直击2023中国经济传媒大会丨北京工商大学数字经济研究院院长白津夫:建设现代化产业体系要以制造业数字化转型为重点

直击2023中国经济传媒大会丨北京工商大学数字经济研究院院长白津夫:建设现代化产业体系要以制造业数字化转型为重点

每经记者:叶晓丹每经实习记者:黄海 每经编辑:陈俊杰《每日经济新闻
06-10 16:41:14
绵阳有什么土特产可以送礼的 报资讯

绵阳有什么土特产可以送礼的 报资讯

关于绵阳有什么土特产可以送礼的的内容,包含绵阳有什么特产可以带?黄
06-10 16:40:07
毛巾怎么洗白 发黄的毛巾怎么洗白

毛巾怎么洗白 发黄的毛巾怎么洗白

1、毛巾去黄。准备洗米剩下的淘米水,将带有污渍的毛巾放在淘米水里,
06-10 16:06:22
夏日游戏节缺乏女性身影 遭多位外媒记者和推特大V批评_观察

夏日游戏节缺乏女性身影 遭多位外媒记者和推特大V批评_观察

今日(6月10日),游戏媒体TheVerge注意到在已经结束的2023夏日游戏节
06-10 15:30:04
【环球财经】投资者乐观情绪推动  纽约股市三大股指9日均上涨

【环球财经】投资者乐观情绪推动 纽约股市三大股指9日均上涨

由于投资者保持乐观预期,纽约股市三大股指在9日高开,截至当天收盘,
06-10 14:40:28

为您推荐

精彩推送