检查在x64平台上分配一定数量内存的可能性
本文关键字:内存 可能性 x64 平台 分配 检查 | 更新日期: 2023-09-27 18:09:58
我有一个应用程序使用了大量内存,但这是正常情况。如果没有足够的内存来执行操作,我需要通知用户。我知道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平台上分配一定量内存的可能性?
这根本不是Windows的工作方式。它是虚拟内存操作系统。当您不能再分配更多的虚拟内存时,您将获得OOM。物理内存(RAM)与此无关。
当你的代码在32模式下运行时,它有2gb的可寻址虚拟内存。当您尝试分配一块内存并且没有足够大的空间来容纳请求时,就会发生OOM。较大的分配较早失败。永远不要以为你可以分配所有的内存,一旦一个程序分配了超过1gb的内存,它失败的几率就会迅速增加。
在64位操作系统上解决的问题。可寻址虚拟内存大小介于192gb和2tb之间,具体取决于Windows版本。现在的限制是这个巨大的地址空间中有多少是可映射的。分页文件的最大大小。这是一个移动的目标,分页文件由其他进程共享。当你接近极限时,你就会遇到更大的问题,比如垃圾收集需要花很长时间。你不必再费心告诉用户她离OOM有多近了,她已经从你的程序不再响应中知道了。
请参阅MemoryFailPoint,了解一种验证分配的方法,而不需要尝试拦截OutOfMemoryException的不可预测性。注意,这既适用于x86,也适用于x64。