Skip to content

Commit

Permalink
Fix GCMemoryInfo.TotalAvailableMemoryBytes under Wow (dotnet#55387)
Browse files Browse the repository at this point in the history
  • Loading branch information
jkotas authored Jul 9, 2021
1 parent 164a0c0 commit 43cdfa1
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 7 deletions.
6 changes: 6 additions & 0 deletions src/coreclr/gc/windows/gcenv.windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
7 changes: 7 additions & 0 deletions src/coreclr/vm/gcenv.os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
16 changes: 9 additions & 7 deletions src/libraries/System.Runtime/tests/System/GCTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 43cdfa1

Please sign in to comment.