对于win32可执行文件(x86),我们可以设置LargeAddressAware标志,以便在x64 Windows上运行时可以访问4 GB(而不是2 GB)的虚拟地址空间。
这看起来非常有吸引力。 但是,有风险涉及。
例如,请参阅: 在32位Windows可执行文件中使用/ LARGEADDRESSAWARE的缺点?
因此,让我们继续并configuration正在执行一些unit testing的系统范围registry开关AllocationPreference
设置为MEM_TOP_DOWN
。
应该这样做,不是吗?
它不!
问题是Visual Studio的x86“testing运行器”(执行引擎)本身不是LAA。
这个父进程只会看到“低”2 GB的VAS,我们的模块也会被testing。
来自VS2013.1的例子
mstest.exe
产生QTAgent32.exe
vstest.console.exe
产生vstest.executionengine.x86.exe
他们都不是LAA启用!
那么使用启用LAA的x86testing运行器的推荐方法是什么?
这里有一个代码片段(VSunit testing,csharp)来检查LAA执行环境。
除非它成功了你的testing环境是不适合你有一套unit testing(也)覆盖与LAA的兼容性:
using System; using System.Diagnostics; using System.Runtime.InteropServices; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace TestCheckEnv32LAA { [TestClass] public class CheckEnv32LAA { #region [Native DLL import] [Flags()] public enum AllocationType : uint { COMMIT = 0x1000, RESERVE = 0x2000, RESET = 0x80000, LARGE_PAGES = 0x20000000, PHYSICAL = 0x400000, TOP_DOWN = 0x100000, WRITE_WATCH = 0x200000 } [Flags()] public enum MemoryProtection : uint { EXECUTE = 0x10, EXECUTE_READ = 0x20, EXECUTE_READWRITE = 0x40, EXECUTE_WRITECOPY = 0x80, NOACCESS = 0x01, READONLY = 0x02, READWRITE = 0x04, WRITECOPY = 0x08, GUARD_Modifierflag = 0x100, NOCACHE_Modifierflag = 0x200, WRITECOMBINE_Modifierflag = 0x400 } [StructLayout(LayoutKind.Sequential)] struct MEMORYSTATUSEX { 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; } [DllImport("kernel32.dll")] extern static void GlobalMemoryStatusEx(ref MEMORYSTATUSEX status); [DllImport("kernel32.dll", SetLastError = true)] public static extern UIntPtr VirtualAlloc(UIntPtr lpAddress, UIntPtr dwSize, AllocationType flAllocationType, MemoryProtection flProtect); #endregion public CheckEnv32LAA() { } [TestMethod] public void CheckEnvironment32LAA() { // check for a suitable environment to test modules for compatibility with LargeAddressAware (LAA): // 1) OS must be x64 // 2) test runner must be x86 // 3) test runner must be LAA enabled itself // 4) memory allocation (with manual TopDown flag) must happen beyond the 2 GB boundary // 5) memory allocation (with default settings) must happen beyond the 2 GB boundary // // RE 3) this requirement is true for "regular" unit tests (to test DLL modules). it does not apply // for any tests spawning the application (EXE) to be tested as a separate process. // // RE 5) a failure indicates the following registry switch has not been set: // [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management] // "AllocationPreference"=dword:00100000 // // see: // https://stackoverflow.com/questions/2288728/ String sParentProcName = Process.GetCurrentProcess().MainModule.FileName; //CHECK_1 Assert.IsTrue(Environment.Is64BitOperatingSystem, "Test is not executing on x64 OS"); //CHECK_2 Assert.IsFalse(Environment.Is64BitProcess, "Test runner is not x86: " + sParentProcName); //CHECK_3 MEMORYSTATUSEX tmpStatus = new MEMORYSTATUSEX(); tmpStatus.dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX)); tmpStatus.ullTotalPhys = 0; GlobalMemoryStatusEx(ref tmpStatus); ulong uVM = tmpStatus.ullTotalVirtual; Assert.IsTrue(uVM > 0x80000000, "Test runner is not LAA enabled (max: " + uVM / (1024 * 1024) + "): " + sParentProcName); Assert.IsTrue(uVM <= 0x100000000, "Test runner is not x86 (max: " + uVM / (1024 * 1024) + "): " + sParentProcName); //CHECK_4 UIntPtr pMem = UIntPtr.Zero; ulong uAddress = 0; pMem = VirtualAlloc(UIntPtr.Zero, (UIntPtr)1024, AllocationType.RESERVE | AllocationType.TOP_DOWN, MemoryProtection.READWRITE); uAddress = (ulong)pMem; Assert.IsTrue(uAddress > 0x80000000, "Test runner is not LAA enabled (highest: " + uAddress / (1024 * 1024) + "): " + sParentProcName); //CHECK_5 pMem = VirtualAlloc(UIntPtr.Zero, (UIntPtr)1024, AllocationType.RESERVE, MemoryProtection.READWRITE); uAddress = (ulong)pMem; Assert.IsTrue(uAddress > 0x80000000, "System-wide MEM_TOP_DOWN is not set (allocated at: " + uAddress / (1024 * 1024) + ")"); } } }
到目前为止,我只是遇到了一些建议, editbin.exe
了问题中列出的Microsoft二进制文件(例如使用editbin.exe
手动“修补”它们)。 但是这有以下缺点:
看来一个适当的长期解决方案将不得不由微软实施?
http://visualstudio.uservoice.com/forums/196039-microsoft-test-tools/suggestions/5781437