From c7baa966ee756239dffe71f1fc47bb922d602a3b Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Fri, 9 Jul 2021 00:01:43 -0700 Subject: [PATCH] Fix GCMemoryInfo.TotalAvailableMemoryBytes under Wow Fixes #55126 --- src/coreclr/gc/windows/gcenv.windows.cpp | 6 ++++++ src/coreclr/vm/gcenv.os.cpp | 7 +++++++ .../System.Runtime/tests/System/GCTests.cs | 16 +++++++++------- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/coreclr/gc/windows/gcenv.windows.cpp b/src/coreclr/gc/windows/gcenv.windows.cpp index 7bebc596f5ec71..4d53d1ed0dfe23 100644 --- a/src/coreclr/gc/windows/gcenv.windows.cpp +++ b/src/coreclr/gc/windows/gcenv.windows.cpp @@ -983,6 +983,12 @@ uint64_t GCToOSInterface::GetPhysicalMemoryLimit(bool* is_restricted) MEMORYSTATUSEX memStatus; GetProcessMemoryLoad(&memStatus); assert(memStatus.ullTotalPhys != 0); + + // For 32-bit processes the virtual address range could be smaller than the amount of physical + // memory on the machine/in the container, we need to restrict by the VM. + if (memStatus.ullTotalVirtual < memStatus.ullTotalPhys) + return memStatus.ullTotalVirtual; + return memStatus.ullTotalPhys; } diff --git a/src/coreclr/vm/gcenv.os.cpp b/src/coreclr/vm/gcenv.os.cpp index de803cca4310d6..b585df950948d9 100644 --- a/src/coreclr/vm/gcenv.os.cpp +++ b/src/coreclr/vm/gcenv.os.cpp @@ -892,6 +892,13 @@ uint64_t GCToOSInterface::GetPhysicalMemoryLimit(bool* is_restricted) MEMORYSTATUSEX memStatus; GetProcessMemoryLoad(&memStatus); +#ifndef TARGET_UNIX + // For 32-bit processes the virtual address range could be smaller than the amount of physical + // memory on the machine/in the container, we need to restrict by the VM. + if (memStatus.ullTotalVirtual < memStatus.ullTotalPhys) + return memStatus.ullTotalVirtual; +#endif + return memStatus.ullTotalPhys; } diff --git a/src/libraries/System.Runtime/tests/System/GCTests.cs b/src/libraries/System.Runtime/tests/System/GCTests.cs index 2e86776345c43c..d7b7bcd24e1da8 100644 --- a/src/libraries/System.Runtime/tests/System/GCTests.cs +++ b/src/libraries/System.Runtime/tests/System/GCTests.cs @@ -813,11 +813,13 @@ public static void GetGCMemoryInfo() GCMemoryInfo memoryInfo1 = GC.GetGCMemoryInfo(); - Assert.InRange(memoryInfo1.HighMemoryLoadThresholdBytes, 1, long.MaxValue); - Assert.InRange(memoryInfo1.MemoryLoadBytes, 1, long.MaxValue); - Assert.InRange(memoryInfo1.TotalAvailableMemoryBytes, 1, long.MaxValue); - Assert.InRange(memoryInfo1.HeapSizeBytes, 1, long.MaxValue); - Assert.InRange(memoryInfo1.FragmentedBytes, 0, long.MaxValue); + long maxVirtualSpaceSize = (IntPtr.Size == 4) ? uint.MaxValue : long.MaxValue; + + Assert.InRange(memoryInfo1.HighMemoryLoadThresholdBytes, 1, maxVirtualSpaceSize); + Assert.InRange(memoryInfo1.MemoryLoadBytes, 1, maxVirtualSpaceSize); + Assert.InRange(memoryInfo1.TotalAvailableMemoryBytes, 1, maxVirtualSpaceSize); + Assert.InRange(memoryInfo1.HeapSizeBytes, 1, maxVirtualSpaceSize); + Assert.InRange(memoryInfo1.FragmentedBytes, 0, maxVirtualSpaceSize); GCHandle[] gch = new GCHandle[64 * 1024]; for (int i = 0; i < gch.Length * 2; ++i) @@ -849,10 +851,10 @@ public static void GetGCMemoryInfo() Assert.Equal(memoryInfo2.TotalAvailableMemoryBytes, memoryInfo1.TotalAvailableMemoryBytes); scenario = nameof(memoryInfo2.HeapSizeBytes); - Assert.InRange(memoryInfo2.HeapSizeBytes, memoryInfo1.HeapSizeBytes + 1, long.MaxValue); + Assert.InRange(memoryInfo2.HeapSizeBytes, memoryInfo1.HeapSizeBytes + 1, maxVirtualSpaceSize); scenario = nameof(memoryInfo2.FragmentedBytes); - Assert.InRange(memoryInfo2.FragmentedBytes, memoryInfo1.FragmentedBytes + 1, long.MaxValue); + Assert.InRange(memoryInfo2.FragmentedBytes, memoryInfo1.FragmentedBytes + 1, maxVirtualSpaceSize); scenario = null; }