none
存取特定實體記憶體, MemoryMappedFiles RRS feed

  • 問題

  • 目前有一需求要存取某段實體記憶體, 找到了相關文章, 像是黑暗執行續的關於Shared Memory 的兩三事

    請問使用MemoryMappedFiles.CreateNew()的記憶體空間是在實體記憶體嗎?

    那如果我知道我要存取的記憶體位址 是不是就可以透過MemoryMappedFiles來存取?

    或是我搞錯了他的用法? 

    是否有其他存取Physical Memory的方法? 目前只想到開發driver

    請前輩們指點 謝謝


    • 已編輯 頑張る 2019年11月19日 上午 08:49
    2019年11月19日 上午 06:45

解答

  • 你应该是搞错了,MemoryMappedFiles叫做“内存映射文件”,通俗讲就是“虚拟内存”。换句话说就是在磁盘上开辟一块区域,用它来充当内存。这么做可以节省实际物理内存,比如下载大文件(例如在线安装Visual Studio),若指定不使用缓存则还可以避免断电导致的数据丢失。另外也可以加快启动速度,避免从磁盘复制大量数据到物理内存。另一个作用是不同的Process间传递数据,避免复制导致的开销。除了使用MemoryMappedFiles来创建内存映射文件外,所有已编译的exe和dll本身都是内存映射文件,启动时直接由操作系统将磁盘地址映射到虚拟内存地址空间中,每当用到指定数据时再通过“页交换”装载到实际物理内存中,这就是为什么程序能够快速启动的原因。


    运行在ring3态的程序是无法直接访问物理内存的,要想访问物理内存必须运行在ring0态,也就是说你必须写驱动来实现。不过直接访问物理内存必须格外小心,因为当前的Windows在内存保护方面是很严格的,很容易搞出蓝屏。另外为了防范黑客,可能此类驱动还需要签名,具体这方面的东西或许你得直接联系微软了。
    • 已標示為解答 頑張る 2019年11月20日 上午 01:07
    2019年11月19日 上午 09:56
  • 我认为你这里有一个概念性误解,unmanaged指的是“非托管内存”,而不是“物理内存”。“托管”是.Net中的概念,在.Net中堆内存(heap)是垃圾回收器自动控制的,这被称之为“托管内存”。非托管内存不受垃圾回收器管理,但仍然是虚拟内存,在Windows操作系统中所有程序使用的内存全部都是虚拟内存。关于Windows操作系统的工作原理你可以参看此书(https://www.amazon.com/Windows-via-Jeffrey-M-Richter/dp/0735624240/ref=sr_1_2?keywords=Windows+via+C%2FC%2B%2B&qid=1574163556&sr=8-2),这本书极为详细的讲解了Windows的每一个细节。

    不清楚你目前究竟是要使用“非托管内存”还是“物理内存”?按说一般情况下是用不着访问物理内存的,除非是学习实验,否则只有硬件检测等系统级专业程序才会需要这种功能。你是要做这种功能么?

    • 已標示為解答 頑張る 2019年11月20日 上午 01:07
    2019年11月19日 上午 11:50
  • 我这里补充一下。你所说的这个MemoryMappedFiles.CreateNew,实际上是内存映射文件的一种特殊用法。内存映射文件通常包括两部分,磁盘上的文件和物理内存中的缓存,不过可以只使用其中一部分。不使用缓存时通常是为了应对断电等意外,这可以避免这种情况下的数据丢失,这是一种特殊用法。不使用磁盘文件的情况通常是Process间共享或传递数据,这也是一种特殊用法。在Windows操作系统中不仅整个操作系统的内存都是虚拟内存,分配给每个Process的还是单独的虚拟内存,每个Process都有自己独立的内存地址空间。换句话说就是0x1这个地址在A程序和B程序中分别指向不同的操作系统虚拟内存位置,这个位置最后再转换成物理内存的地址。使用内存映射文件后,多个Process可以共用同一段操作系统虚拟内存。虽然在每一个Process中地址可能不同,但最终都指向操作系统中的同一段虚拟内存空间,这就实现了数据共享。所有这些并不涉及物理内存。
    • 已標示為解答 頑張る 2019年11月20日 上午 01:07
    2019年11月19日 下午 12:03

所有回覆

  • 你应该是搞错了,MemoryMappedFiles叫做“内存映射文件”,通俗讲就是“虚拟内存”。换句话说就是在磁盘上开辟一块区域,用它来充当内存。这么做可以节省实际物理内存,比如下载大文件(例如在线安装Visual Studio),若指定不使用缓存则还可以避免断电导致的数据丢失。另外也可以加快启动速度,避免从磁盘复制大量数据到物理内存。另一个作用是不同的Process间传递数据,避免复制导致的开销。除了使用MemoryMappedFiles来创建内存映射文件外,所有已编译的exe和dll本身都是内存映射文件,启动时直接由操作系统将磁盘地址映射到虚拟内存地址空间中,每当用到指定数据时再通过“页交换”装载到实际物理内存中,这就是为什么程序能够快速启动的原因。


    运行在ring3态的程序是无法直接访问物理内存的,要想访问物理内存必须运行在ring0态,也就是说你必须写驱动来实现。不过直接访问物理内存必须格外小心,因为当前的Windows在内存保护方面是很严格的,很容易搞出蓝屏。另外为了防范黑客,可能此类驱动还需要签名,具体这方面的东西或许你得直接联系微软了。
    • 已標示為解答 頑張る 2019年11月20日 上午 01:07
    2019年11月19日 上午 09:56
  • 你应该是搞错了,MemoryMappedFiles叫做“内存映射文件”,通俗讲就是“虚拟内存”。换句话说就是在磁盘上开辟一块区域,用它来充当内存。这么做可以节省实际物理内存,比如下载大文件(例如在线安装Visual Studio),若指定不使用缓存则还可以避免断电导致的数据丢失。另外也可以加快启动速度,避免从磁盘复制大量数据到物理内存。另一个作用是不同的Process间传递数据,避免复制导致的开销。除了使用MemoryMappedFiles来创建内存映射文件外,所有已编译的exe和dll本身都是内存映射文件,启动时直接由操作系统将磁盘地址映射到虚拟内存地址空间中,每当用到指定数据时再通过“页交换”装载到实际物理内存中,这就是为什么程序能够快速启动的原因。


    运行在ring3态的程序是无法直接访问物理内存的,要想访问物理内存必须运行在ring0态,也就是说你必须写驱动来实现。不过直接访问物理内存必须格外小心,因为当前的Windows在内存保护方面是很严格的,很容易搞出蓝屏。另外为了防范黑客,可能此类驱动还需要签名,具体这方面的东西或许你得直接联系微软了。

    謝謝[-]的詳細解說, 學到了很多!

    那如果使用Unmanaged DLL是不推薦嗎? (沒試過還不清楚做法)

    2019年11月19日 上午 10:38
  • 我认为你这里有一个概念性误解,unmanaged指的是“非托管内存”,而不是“物理内存”。“托管”是.Net中的概念,在.Net中堆内存(heap)是垃圾回收器自动控制的,这被称之为“托管内存”。非托管内存不受垃圾回收器管理,但仍然是虚拟内存,在Windows操作系统中所有程序使用的内存全部都是虚拟内存。关于Windows操作系统的工作原理你可以参看此书(https://www.amazon.com/Windows-via-Jeffrey-M-Richter/dp/0735624240/ref=sr_1_2?keywords=Windows+via+C%2FC%2B%2B&qid=1574163556&sr=8-2),这本书极为详细的讲解了Windows的每一个细节。

    不清楚你目前究竟是要使用“非托管内存”还是“物理内存”?按说一般情况下是用不着访问物理内存的,除非是学习实验,否则只有硬件检测等系统级专业程序才会需要这种功能。你是要做这种功能么?

    • 已標示為解答 頑張る 2019年11月20日 上午 01:07
    2019年11月19日 上午 11:50
  • 我这里补充一下。你所说的这个MemoryMappedFiles.CreateNew,实际上是内存映射文件的一种特殊用法。内存映射文件通常包括两部分,磁盘上的文件和物理内存中的缓存,不过可以只使用其中一部分。不使用缓存时通常是为了应对断电等意外,这可以避免这种情况下的数据丢失,这是一种特殊用法。不使用磁盘文件的情况通常是Process间共享或传递数据,这也是一种特殊用法。在Windows操作系统中不仅整个操作系统的内存都是虚拟内存,分配给每个Process的还是单独的虚拟内存,每个Process都有自己独立的内存地址空间。换句话说就是0x1这个地址在A程序和B程序中分别指向不同的操作系统虚拟内存位置,这个位置最后再转换成物理内存的地址。使用内存映射文件后,多个Process可以共用同一段操作系统虚拟内存。虽然在每一个Process中地址可能不同,但最终都指向操作系统中的同一段虚拟内存空间,这就实现了数据共享。所有这些并不涉及物理内存。
    • 已標示為解答 頑張る 2019年11月20日 上午 01:07
    2019年11月19日 下午 12:03
  • MemoryMappedFiles可以應用在兩個程式的資料交換, 也就是向系統要一塊記憶體空間, 做為兩個程式交換之用, 例如你寫我讀, 我寫你讀, 並非支援存取某段實體記憶體的用途
    2019年11月19日 下午 02:18
  • 謝謝解說 讓我更了解MemoryMappedFiles的細節意義與用法!
    2019年11月20日 上午 01:07