Repository navigation
Description
Background and motivation
The System.Environment class has many useful properties regarding the environment where the process runs, but it doesn't currently have properties about the total and free amount of physical and virtual memories. These are very important metrics, especially for computation-intensive projects like ML.NET's machine learning.
It would be great if the Environment class would have more properties describing the total and free amounts of physical and virtual memories.
API Proposal
namespace System
{
public static partial class Environment
{
public static long? TotalPhysicalMemory { get; }
public static long? FreePhysicalMemory { get; }
public static long? TotalVirtualMemory { get; }
public static long? FreeVirtualMemory { get; }
}
}API Usage
// Get the total physical memory (in bytes)
var totalRam = Environment.TotalPhysicalMemory;
// Get the total physical memory (in bytes)
var freeRam = Environment.FreePhysicalMemory ;
// Get the total physical memory (in bytes)
var totalVM = Environment.TotalVirtualMemory;
// Get the total physical memory (in bytes)
var freeVM = Environment.FreeVirtualMemory;Alternative Designs
if (OperatingSystem.IsWindows())
{
ObjectQuery wql = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(wql);
ManagementObjectCollection results = searcher.Get();
foreach (ManagementObject result in results)
{
ulong totalVisibleMemorySize = (ulong)result["TotalVisibleMemorySize"];
ulong freePhysicalMemory = (ulong)result["FreePhysicalMemory"];
ulong totalVirtualMemorySize = (ulong)result["TotalVirtualMemorySize"];
ulong freeVirtualMemory = (ulong)result["FreeVirtualMemory"];
}
}Risks
It's not a risk per say, but these new properties would require some extra work, because we would need to call platform-specific APIs. Virtual memory is used on Windows, Linux, Android and iOS, so the appropriate APIs should be available on those, but I'm not sure about others that .NET supports.
I would define these new properties as nullable types, because I can image that some .NET supported operating system doesn't support these reports regarding memory usage.
Also, if it's not implemented on a specific platform, they could return null.
Activity
andrasfuchs commentedon Dec 2, 2022
I can't change labels on this issue, but I think the best area label would be
area-System.Diagnostics.Process. @jeffhandleydakersnar commentedon Feb 10, 2023
Unfortunately, if you are referring to managed memory, the GC is going to make this set of APIs unfeasible. The GC will often only collect when allocations are requested, so at any given moment, the amount of memory that is technically free (which is what your API would return) could be way smaller than the amount of memory that would be free after a GC run. The only way to produce an accurate answer would be to kick off a GC run before checking how much free memory there is, but that would be both expensive and inconsistent. Closing for this reason, but feel free to request a reopen if I'm missing something.
andrasfuchs commentedon Feb 14, 2023
I partially agree with your reasoning, but I still think that having an API to get the free memory would be useful.
In our use case for example, ML.NET often runs unmanaged code for the machine learning training process and knowing the available free memory during that training would be crucial, because we need to prevent a system-wide crash that normally happens if we don't cancel the training on time before we run out of virtual memory.
I agree that calling GC before every free memory call would be wasteful and impractical.
tannergooding commentedon Feb 14, 2023
Checks against the "virtual memory space" aren't typically meaningful. On a 64-bit system, you'll have at least 48-bits of addressable virtual address space. The more meaningful information is the available physical memory.
If such an API were provided, it would likely be part of
System.Runtime.InteropServices.NativeMemoryas that is where theAlloc/FreeAPIs are exposed.That being said, there are often better ways to manage such memory than simply checking how much physical memory is available and there can often be other considerations required as part of that. If you know you're working with large data and can do streaming, it is often more beneficial to have your algorithms use that to minify the amount of total overhead required.
andrasfuchs commentedon Mar 6, 2023
As far as I know the virtual memory space is also constrained by the space available on the swap partition(s) and/or the maximum swap file size settings, so the total and free virtual memory is a useful metric, especially in the use cases like ours with ML.NET, because if we don't monitor it closely it can cause a system-wide crash.
From he user's perspective it would make more sense to have these values available on the
System.Environmentclass, that's where we would look for it, even if the actual memory allocations are happening elsewhere.ericstj commentedon Jun 14, 2024
This came up again recently where folks are using System.Management for this as we have no lower level API. System.Management is very heavy and not currently AOT friendly nor cross-plat. It would be good if we could expose some API here for diagnostics purposes.
tannergooding commentedon Jul 12, 2026
CC. @jkotas here as well for input. There's a lot of things that can subtly go wrong or be misinformed with such APIs and when doing such lowlevel memory management we've typically said to just use platform specific APIs, which are better setup for that type of thing. So I'm still leaning towards closing this.
jkotas commentedon Jul 12, 2026
Providing the raw total and free physical memory sizes is really only useful for diagnostics. For example, an application may include these values in crash-report telemetry. They do not indicate how much of the free physical memory is actually available to the current process.
We already expose
GCMemoryInfo.TotalAvailableMemoryandGCMemoryInfo.MemoryLoadBytes, which account for configuration and policies such as Windows job object limits and Linux cgroup limits. TheseGCMemoryInfoAPIs are better suited for scenarios like dynamically tuning cache sizes.This proposal is similar to #29686, which requests exposing the machine's raw total CPU core count without applying any policy constraints.
I don't think APIs that expose raw machine characteristics belong in the BCL.