問題描述:
使用GlobalMemoryStatus在32位(x86)上運作沒有問題,但是轉用64位出現問題(.net framework 4.5),擷取的記憶體數值不正确,并且運作後報錯"嘗試讀取或寫入受保護的記憶體",這段32位的代碼如下:
[StructLayout(LayoutKind.Sequential)]
private struct MEMORYSTATUS
{
public uint dwLength;
public uint dwMemoryLoad;
public uint ullTotalPhys;
public uint ullAvailPhys;
public uint ullTotalPageFile;
public uint ullAvailPageFile;
public uint ullTotalVirtual;
public uint ullAvailVirtual;
}
[DllImport("Kernel32.dll")]
private static extern void GlobalMemoryStatus(ref MEMORYSTATUS lpBuffer);
static void Main()
{
MEMORYSTATUS stat = new MEMORYSTATUS();
GlobalMemoryStatus(ref stat);
}
解決問題:
根據網上的描述,可能是64位資料溢出,也有可能是“對于記憶體超過4 GB的計算機,GlobalMemoryStatus函數可能會傳回不正确的資訊,報告值為-1,表明溢出。出于這個原因,應用程式應使用GlobalMemoryStatusEx函數代替。”是以考慮用GlobalMemoryStatusEx,貼上我的64位代碼。可以看到有幾處不同:
1. uint->ulong,64位确實需要ulong類型,不然資料傳回值為0,擷取過程fail;
2. 使用了GlobalMemoryStatusEx;
3. 對statEx配置設定了空間:statEX.dwLength = (uint)Marshal.SizeOf(statEX); 如果不加這一句,擷取過程依然fail;
[StructLayout(LayoutKind.Sequential)]
private struct MEMORYSTATUS
{
public uint dwLength;
public uint dwMemoryLoad;
public ulong ullTotalPhys;
public ulong ullAvailPhys;
public ulong ullTotalPageFile;
public ulong ullAvailPageFile;
public ulong ullTotalVirtual;
public ulong ullAvailVirtual;
public ulong ullAvailExtendedVirtual;
}
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("Kernel32.dll")]
private static extern bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX lpBuffer);
static void Main()
{
MEMORYSTATUSEX statEX = new MEMORYSTATUSEX();
statEX.dwLength = (uint)Marshal.SizeOf(statEX);
GlobalMemoryStatusEx(ref statEX);
}