.Net为什么可以';在x64进程中,我不能获得超过11GB的分配内存吗?

.Net为什么可以';在x64进程中,我不能获得超过11GB的分配内存吗?,.net,process,memory-management,.net,Process,Memory Management,我原以为64位进程的最大用户空间是8TB,但我做了一个小测试,可以得到的最大用户空间是10-11GB 注意:我在一个过程中不需要那么多的内存,我只是想了解为什么出于好奇 这是我的测试程序: static void Main(string[] args) { List<byte[]> list = new List<byte[]>(); while (true) { Console.WriteLine("Press any key

我原以为64位进程的最大用户空间是8TB,但我做了一个小测试,可以得到的最大用户空间是10-11GB

注意:我在一个过程中不需要那么多的内存,我只是想了解为什么出于好奇

这是我的测试程序:

static void Main(string[] args)
{
    List<byte[]> list = new List<byte[]>();

    while (true)
    {
        Console.WriteLine("Press any key to allocate 1 more GB");
        Console.ReadKey(true);
        list.Add(new byte[1024 * 1024 * 1024]);

        Console.WriteLine("Memory size:");
        double memoryUsage = Process.GetCurrentProcess().PeakVirtualMemorySize64 / (double)(1024 * 1024 * 1024);
        Console.WriteLine(memoryUsage.ToString("0.00") + " GB");
        Console.WriteLine();
    }
}
static void Main(字符串[]args)
{
列表=新列表();
while(true)
{
Console.WriteLine(“按任意键再分配1 GB”);
Console.ReadKey(true);
添加(新字节[1024*1024*1024]);
Console.WriteLine(“内存大小:”);
double memoryUsage=Process.GetCurrentProcess().PeakVirtualMemorySize64/(double)(1024*1024*1024);
Console.WriteLine(MemorySage.ToString(“0.00”)+“GB”);
Console.WriteLine();
}
}
编辑:

将测试程序更新为更具确定性


为了接受答案,我想知道如果8TB只是理论上的,那么实际最大分配内存是如何计算的。

它是最多8TB,而不是8TB。您可能最多有8 TB,但需要匹配的RAM/交换文件。

尝试分配一个块(而不是1MB块的列表):

编辑-根据您的评论,您只有4GB的物理RAM,您真的没有必要分配>~8GB,甚至这也在推动它

编辑-

为了接受一个答案,我想知道如果8TB只是理论上的,实际最大分配内存是如何计算的

您可以分配的最大RAM量可能等于(页面文件大小-RAM中所有内容的大小,不能或不会分页的除外)+(物理RAM大小-无法或不会分页的所有内容的大小,即保持系统运行所需的大小…内核、驱动程序、.net内容等)

当然,页面文件可以增长

迟早,从磁盘到磁盘的分页会变得太多,系统会慢到爬行,变得不可用

阅读马克·鲁西诺维奇的博客:


    • 我猜是因为您使用的是一个列表,我认为它有一个内部限制

      看看如果你尝试创建自己的旧学校列表,你会得到什么:

      public class ListItem<T>
      {
          public ListItem Parent;
          public T Value;
      
          public ListItem(ListItem<T> parent, T item)
          {
              this.Parent = parent;
              this.Value = item;
          }
      }
      
      公共类列表项
      {
      公共列表项父项;
      公共价值观;
      公共ListItem(ListItem父项,T项)
      {
      这个。父=父;
      该值=项目;
      }
      }
      
      我以前写过几乎完全相同的代码(只有我的项目是一个int),并在一台有32个处理器和128 GB ram的机器上运行,无论发生什么,它总是以相同的大小运行,并且总是与Int32.MaxValue相关,希望能有所帮助。

      这是您的机器

      我有一个8GB内存和12GB页面文件的x64,我运行了你的程序,最高达到16.23GB

      EPILOG:然后我的Win7安装逐渐陷入昏迷状态,因为关键进程显然内存不足

      编辑:如果您想了解Windows如何分配(即保留和提交)内存,请阅读并重试


      由于.Net依赖Windows来管理它用来构建GC堆的内存,Windows如何做到这一点的机制反映在.Net如何在较低级别上分配内存上。

      您的系统有多少内存?Vista x64 Ultimate上可能有12GB?4GB的物理内存,在发生
      OutOfMemoryException
      异常之前可能会填满物理RAM和交换文件。我想知道如果RAM完全满了会发生什么。
      抛出新的OutOfMemoryException
      是如何执行的?@earlz-抛出该异常的内存已由运行时分配。
      列表
      最多可以包含
      Int32.MaxValue/2
      项(因为它使用Int32索引项)。但是OP在1MB的块中达到10GB,所以他只分配了大约10000个块。。。这远远没有达到极限。另外,你不需要重新创建链接列表,BCL中已经有一个
      LinkedList
      类…感谢你对LinkedList的引用,我很少使用它们,所以我不知道它在那里。是的!640KB应该足够了anybody@Terry-用得太多了。。。甚至都不好笑……~说真的,如果您试图在Windows机器上分配超过两倍的物理RAM,您最好重新考虑分配策略。使用内存映射文件等…
      关键进程显然内存不足。
      Ha!我认为关键进程正是Win7不希望饿死的进程:)好吧,当内存消失时,它就消失了!
      public class ListItem<T>
      {
          public ListItem Parent;
          public T Value;
      
          public ListItem(ListItem<T> parent, T item)
          {
              this.Parent = parent;
              this.Value = item;
          }
      }