检查在x64平台上分配一定量内存的可能性

发布于 2024-12-07 02:41:02 字数 1706 浏览 0 评论 0原文

我有一个应用程序使用大量内存,但这是正常情况。如果没有足够的内存来执行操作,我需要通知用户。 我知道 x86 进程可以分配少于 2 GB 的用户内存。但是 x64 进程可以根据物理内存分配更多的用户内存。 早些时候,该应用程序仅支持 x86 平台,我使用了以下代码:

private bool CheckMemoryInternal(long bytesCountToCheck) {

 // Get physical memory of the current workstation
 long memSize = long.MaxValue;
 NativeMethods.MEMORYSTATUSEX memory = new NativeMethods.MEMORYSTATUSEX();
 memory.dwLength = (uint)System.Runtime.InteropServices.Marshal.SizeOf(memory);
 if (UnsafeNativeMethods.GlobalMemoryStatusEx(ref memory))
   memSize = (long)memory.ullTotalPhys;

 // Don't know the reason, but this value is measured in kilobytes, and MSDN wrote that it is measured in bytes
 long maxWorkingSet = (long)Process.GetCurrentProcess().MaxWorkingSet * 1024;

 // Obtain the maximal amount of memory for our app
 // If the current amount of physical memory is less than maxWorkingSet, we can use it, but it should not be less than 512 MB for our application.
 long maxMemorySize = Math.Min(Math.Max(512 * OneMegaByte, memSize), maxWorkingSet);

 return bytesCountToCheck + Process.GetCurrentProcess().PrivateMemorySize64 < maxMemorySize;
}

我知道还有一种方法可以做到这一点:

private bool CheckMemoryInternal(long megaBytes) {

  try {
    byte[][] chunks = new byte[megaBytes][];
    for (int i = 0; i < chunks.Length; i++)
      chunks[i] = new byte[1024 * 1024];
    return true;
  }
  catch (OutOfMemoryException) {
    return false;
  }
}

但我不喜欢这种方式。

现在我将应用程序迁移到 x64 平台。起初,代码示例无法正常工作。用于分配的允许内存的最大大小与 x86 应用程序中相同(MaxWorkingSet(32 位)== MaxWorkingSet(64 位))。 我尝试在 x64 机器上分配大量内存并且成功了。我能够在具有 4Gb 物理内存的 x64 计算机上分配 4Gb 内存,之后出现 OutOfMemory 异常。

如何检查在 x64 平台上分配一定量内存的可能性?

I have an application that uses a lot of memory, but it is a normal situation. I need to inform user if there is not enough memory to perform an operation.
I know that x86 process can allocate less then 2 GB user memory. But x64 process can allocate much more user memory depending on physical memory.
Earlier the application supported x86 platform only and I used the following code:

private bool CheckMemoryInternal(long bytesCountToCheck) {

 // Get physical memory of the current workstation
 long memSize = long.MaxValue;
 NativeMethods.MEMORYSTATUSEX memory = new NativeMethods.MEMORYSTATUSEX();
 memory.dwLength = (uint)System.Runtime.InteropServices.Marshal.SizeOf(memory);
 if (UnsafeNativeMethods.GlobalMemoryStatusEx(ref memory))
   memSize = (long)memory.ullTotalPhys;

 // Don't know the reason, but this value is measured in kilobytes, and MSDN wrote that it is measured in bytes
 long maxWorkingSet = (long)Process.GetCurrentProcess().MaxWorkingSet * 1024;

 // Obtain the maximal amount of memory for our app
 // If the current amount of physical memory is less than maxWorkingSet, we can use it, but it should not be less than 512 MB for our application.
 long maxMemorySize = Math.Min(Math.Max(512 * OneMegaByte, memSize), maxWorkingSet);

 return bytesCountToCheck + Process.GetCurrentProcess().PrivateMemorySize64 < maxMemorySize;
}

I know one more way to do that:

private bool CheckMemoryInternal(long megaBytes) {

  try {
    byte[][] chunks = new byte[megaBytes][];
    for (int i = 0; i < chunks.Length; i++)
      chunks[i] = new byte[1024 * 1024];
    return true;
  }
  catch (OutOfMemoryException) {
    return false;
  }
}

But I don't like this way.

Now I migrated the application to the x64 platform. And at first the code sample didn't work correctly. The maximal size of the allowed memory used for allocating remained the same as in the x86 application (MaxWorkingSet(32 bit) == MaxWorkingSet(64 bit)).
I tried to allocate a lot of memory on a x64 machine and I succeeded. I was able to allocate 4Gb memory on a x64 machine with 4Gb physical memory, and after that I've got the OutOfMemory exception.

How can I check the possibility of allocating a certain amount of memory on the x64 platform?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小苏打饼 2024-12-14 02:41:02

Windows 根本不是这样工作的。它是一个虚拟内存操作系统。当您无法再分配更多虚拟内存时,就会发生 OOM。物理内存(RAM)与此无关。

当您的代码在 32 模式下运行时,它具有 2 GB 的可寻址虚拟内存。当您尝试分配一块内存但没有足够大的空间来满足请求时,就会发生 OOM。大量分配会更早失败。永远不要假设您可以分配所有内容,一旦程序分配了超过一千兆字节,它失败的可能性就会开始迅速增加。

64 位操作系统上已解决的问题。可寻址虚拟内存大小介于 192 GB 和 2 TB 之间,具体取决于 Windows 版本。现在的限制是巨大的地址空间中有多少是可映射的。页面文件的最大大小。这是一个移动目标,分页文件被其他进程共享。当你接近极限时,你会遇到更大的问题,比如永远需要进行垃圾收集。您只需不再费心告诉用户她距离 OOM 有多近,她已经从您的程序中知道不再有响应了。

Windows Internals 是一本了解 Windows 工作方式的好书。

That's not at all how Windows works. It is a virtual memory operating system. You get OOM when you can no longer allocate any more virtual memory. Physical memory (RAM) has nothing to do with it.

When your code runs in 32-mode, it has 2 gigabytes of addressable virtual memory. OOM happens when you try to allocate a chunk of memory and there isn't a hole left that's big enough to fit the request. Large allocations fail earlier. Never assume you can allocate everything, once a program has allocated more than a gigabyte, the odds that it will fail start to increase rapidly.

A problem that's solved on 64-bit operating system. Addressable virtual memory size is somewhere between 192 gigabytes and 2 terabytes, depends on the Windows version. The constraint is now how much of that huge address space is mappable. The maximum size of the paging file. Which is a moving target, the paging file is shared by other processes. When you get close to the limit you have much bigger problems, like garbage collections that take forever. You just don't bother anymore telling the user how close to OOM she gets, she already knows from your program not being responsive anymore.

Windows Internals is a good book to learn more about the way Windows works.

背叛残局 2024-12-14 02:41:02

请参阅 MemoryFailPoint 了解无需使用尝试拦截 OutOfMemoryException 的不可预测性。请注意,这适用于 x86 和 x64。

See MemoryFailPoint for a way to verify allocations without having the unpredictability of trying to intercept an OutOfMemoryException. Note that this works for x86 as well as for x64.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文