天天看点

c# 64位获取系统内存GlobalMemoryStatusEx问题描述:解决问题:

问题描述:

使用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);
        }