【问题标题】:Staying away from virtual memory in Windows\C++远离 Windows\C++ 中的虚拟内存
【发布时间】:2010-12-24 19:20:11
【问题描述】:

我正在编写一个性能关键型应用程序,其中必须在转储到磁盘之前在物理内存中存储尽可能多的数据。

我可以使用::GlobalMemoryStatusEx(...)::GetProcessMemoryInfo(...) 找出保留\空闲的物理内存百分比以及我当前进程处理的内存量。 使用这些数据,我可以确保在使用约 90% 的物理内存或达到每个应用程序限制的最大 2GB 的约 90 时进行转储。

但是,我想要一种方法来简单地接收在系统开始使用虚拟内存之前实际剩余的字节数,特别是因为应用程序将同时编译为 32 位和 64 位,而 2 GB 限制不存在。

【问题讨论】:

  • 您是否使用动态对象分配并检查您正在使用多少内存?通常,人们将他们的对象预先分配到特定大小,从而节省所有检查开销。
  • 这不是意味着您正在尝试编写自己的虚拟内存管理器吗?还是您再也不会访问转储的数据?
  • 这不是虚拟内存。虚拟内存将程序使用的内存地址与物理内存地址分开。
  • 你不能,如果你能得到任何答案,你得到的答案将立即过时。
  • Erm 我知道大多数“类似网络”的程序员永远不会理解这一点,但是有些应用程序可以从稳定的连续内存空间(如 DOS)中受益而无需交换。问题是 - 使用 Windows VM 是否可以远程执行类似的操作?

标签: c++ windows winapi memory swap


【解决方案1】:

这个功能怎么样:

int
bytesLeftUntilVMUsed() {
    return 0;
}

在我认为的几乎所有情况下,它都应该给出正确的结果;)

【讨论】:

    【解决方案2】:

    想象一下在 256Mb 的 RAM 中运行 Windows 7(MS 建议至少 1GB)。这实际上是您要求用户通过重新分配 90% 的可用 RAM 来执行的操作。

    真正的问题是:为什么需要这么多内存? “性能关键”标准究竟是什么?

    通常,这类问题意味着您的设计存在严重问题。

    更新:

    使用顶级 RAM (DDR3) 可为您提供 12GB/s 的理论传输速度,这相当于在每个时钟周期读取一个 32 位值,并留出一些带宽。我相当肯定,以这种速度进入 CPU 的数据不可能做任何有用的事情——指令处理停顿会中断这个流程。额外的、未使用的带宽可用于向/从硬盘分页数据。使用 RAID,此传输速率可能非常高(大约是 RAM 带宽的 1/16)。因此,在不降低性能的情况下向/从磁盘传输数据并对其进行处理是可行的 - 读取之间只需 16 个周期(好吧,我的数学在这里可能有点错误)。

    但是,如果您将 Windows 混入其中,一切都将付诸东流。您的记忆随时可能消失,您的应用程序可以任意暂停等等。将内存锁定到 RAM 会对整个系统产生不利影响,从而无法达到定位内存的目的。

    如果您解释您要达到的目标和性能标准,这里有很多人会帮助您开发合适的解决方案,因为如果您必须询问系统限制,那您确实做错了。

    【讨论】:

    • 此应用程序不会与其他应用程序同时使用。
    • 因为应用程序需要两个鼠标按钮,而 Mac 只有一个。
    • 啊哈,这是一个带有用户交互的 GUI 应用程序。那么,你肯定不想保留那种内存——如果你这样做,系统将变得非常无响应。在您的应用程序运行时,有很多事情会发生,如果 RAM 有限,即过多的磁盘交换,这将真正减慢系统速度。另外,我说的是“windows”而不是“pc”,因为我在想“linux”或“vxworks”。这不会是视频编辑,还是高分辨率图像编辑?由于它是一个 GUI,您可以欺骗用户认为它比实际响应更快。
    • 实际上这很讽刺,但我很难说服我的老板切换操作系统支持。它是一个使用 50-100gb 数据集的存储管理应用程序,所以我基本上需要知道我一开始的要求是什么。
    • 由于数据集如此之大,我不会担心尽可能多地保存在 RAM 中,无论如何您都必须对数据进行分页。像您建议的那样锁定 RAM 只会对系统产生负面影响。
    【解决方案3】:

    即使您能够阻止应用程序将内存分页到磁盘,您仍然会遇到 VMM 可能将 其他 程序分页到磁盘的问题,这可能也可能影响你的表现。更不用说另一个应用程序可能会启动并消耗您当前占用的内存,从而导致您的一些应用程序内存被调出。你打算如何处理?

    有一种方法可以通过non-paged pool 使用不可分页内存,但是(a)这个池相对较小,并且(b)它由设备驱动程序使用,并且可能只能在内核内部使用。除非您想确保您的系统不是那么稳定,否则也不建议您大量使用它。

    在尝试编写自己的 VMM 或将 Windows 机器本质上变成具有更多内存的 DOS 机器之前,您可能需要重新审视应用程序的设计并尝试解决将内存分页到磁盘的可能性。

    【讨论】:

      【解决方案4】:

      标准的解决方案是不用担心“虚拟”而担心“动态”。

      虚拟内存的“虚拟”部分必须被视为一种硬件功能,您只能通过编写自己的操作系统来击败它。

      然而,对象的动态分配只是您的应用程序的设计。

      静态分配您需要的对象的简单数组。使用这些对象数组。增加和减少那些静态分配的数组的大小,直到出现性能问题。

      【讨论】:

        【解决方案5】:

        哎哟。非分页池(不能交换或分配给进程的 RAM 量)通常为 256 MB。这是 2GB 机器上 12.5% 的 RAM。如果另外 90% 的物理 RAM 将分配给一个进程,那么所有其他应用程序、服务、内核和驱动程序都将剩下 -2.5%。即使您只为您的应用程序分配 85% 的空间,仍然只剩下 2.5% = 51 MB。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-05-25
          • 2014-06-17
          • 2015-09-01
          • 1970-01-01
          • 2021-09-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多