C# 如何找到进程可用的最大RAM?
我正试图编写一个程序,在海量数据集上执行外部合并排序。作为第一步,我需要将数据集分割成适合RAM的块。我有以下问题:C# 如何找到进程可用的最大RAM?,c#,ram,C#,Ram,我正试图编写一个程序,在海量数据集上执行外部合并排序。作为第一步,我需要将数据集分割成适合RAM的块。我有以下问题: 假设我的机器安装了x数量的RAM,是否有 理论上可以提供的最大数量限制 我的流程 当我运行下面的程序时,当它失败时,我得到一个非零值作为可用内存。当仍然有未使用的RAM时,为什么内存分配会失败?内存分配失败时仍有2.8GB的可用RAM。如何解释观察到的行为 List List=新列表(); 尝试 { while(true) { 添加(“随机字符串”); } } 捕获(例外e) {
List List=新列表();
尝试
{
while(true)
{
添加(“随机字符串”);
}
}
捕获(例外e)
{
Microsoft.VisualBasic.Devices.ComputerInfo CI=新的ComputerInfo();
控制台写入线(CI.AvailablePhysicalMemory);
}
以下是您要查找的内容: 获取计算机的可用物理内存总量 注意:您需要添加对Microsoft.VisualBasic的引用 更新: 填充RAM的样本将首先遇到其他一些限制。
如果您的构建不是64位的,它将首先命中OutOfMemory。您应该在解决方案配置中将解决方案更改为针对x64=64位的版本: 其次,列表具有支持的最大数组维度。 通过添加许多小对象,您将首先达到该限制。 下面是一个快速而肮脏的示例,用于创建字符串列表。
(这可能会有更小的代码使用图像等…但我试图保持与您的示例相似。) 当它运行时,它将消耗您所有的RAM,并最终开始分页到磁盘。记住Windows有虚拟RAM,它最终会被用完,但它比普通RAM慢得多。此外,如果它使用了所有这些,那么它甚至可能无法分配空间来实例化ComputerInfo类 注意:请小心,此代码将消耗所有RAM,并可能使系统不稳定
List List=新列表();
尝试
{
对于(UInt32 I=0;I<134217727;I++)
{
列表子列表=新列表();
列表。添加(子列表);
对于(UInt32 x=0;x<134217727;x++)
{
添加(“随机字符串”);
}
}
}
捕获(例外情况除外)
{
控制台写入线(例如消息);
Microsoft.VisualBasic.Devices.ComputerInfo CI=新的ComputerInfo();
控制台写入线(CI.AvailablePhysicalMemory);
}
注意:为了防止使用磁盘,您可以尝试使用类似System.Security.SecureString的东西,它可以防止自己被写入磁盘,但是积累足够的内存会非常缓慢
下面是一个显示物理内存使用情况的测试运行。我从(1)开始跑步
对于最终实现,我建议您使用
ComputerInfo.AvailablePhysicalMemory
值来确定在加载数据之前可以加载多少数据(将部分数据留给操作系统)。同时还要注意将对象锁定在内存中(通常用于封送等),以防止意外使用虚拟内存。可能重复“我正试图编写一个程序对海量数据集执行外部合并排序。”-将数据放入数据库表并按排序顺序查询?@Mitch,在这里,我更感兴趣的是从学术的角度来看外部合并排序的实现,也许您可以尝试一下?例如,您可能会感兴趣的一个类,它允许您检查如果您尝试实时执行相同的操作,内存块是否会引发OutOfMemoryException。但是RAM的总量不会成为.NET中的限制因素(某些例外情况下)对象大小限制为2GB这对任何单个项都是正确的,代码需要通过其他方法分配RAM,比如将其分块加载到集合中,等等。。但问题是可用的最大RAM是多少。他说他正在使用一个数据集。如果是32位操作系统,也会有更多的限制。不久前,我构建了一个C#app,专门测试我可以分配多少RAM,并在一台96GB可用的服务器上运行。我能够成功地分配几乎所有的RAM,但它必须分块分配。。。添加到集合中。我想,你可以编写一个测试程序来计算系统中使用的RAM总量,而不是计算系统中使用的RAM总量,但是它也会尝试使用VirtualRam…因此,这可能不是找到不分页可以使用多少RAM的最佳方法。我已经编辑了答案,ComputerInfo类中有一个属性提供了@Aadith所要查找的内容。
List<string> list = new List<string>();
try
{
while (true)
{
list.Add("random string");
}
}
catch(Exception e)
{
Microsoft.VisualBasic.Devices.ComputerInfo CI = new ComputerInfo();
Console.WriteLine(CI.AvailablePhysicalMemory);
}
private ulong GetMaxAvailableRAM()
{
Microsoft.VisualBasic.Devices.ComputerInfo CI = new ComputerInfo();
return CI.AvailablePhysicalMemory;
}
List<List<string>> list = new List<List<string>>();
try
{
for (UInt32 I = 0; I < 134217727; I++)
{
List<string> SubList = new List<string>();
list.Add(SubList);
for (UInt32 x = 0; x < 134217727; x++)
{
SubList.Add("random string");
}
}
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
Microsoft.VisualBasic.Devices.ComputerInfo CI = new ComputerInfo();
Console.WriteLine(CI.AvailablePhysicalMemory);
}