我想知道为什么我无法在 32 位 .NET 进程中分配超过 1,000 MB 的内存。以下迷你应用程序在分配 1,000 MB 后抛出 OutOfMemoryException。为什么是 1,000 MB,而不是 1.8 GB?是否有我可以更改的流程范围设置?

static void Main(string[] args)
{
    ArrayList list = new ArrayList();
    int i = 0;
    while (true)
    {
        list.Add(new byte[1024 * 1024 * 10]); // 10 MB
        i += 10;
        Console.WriteLine(i);
    }
}

附:垃圾收集没有帮助。

编辑,澄清我想要什么: 我编写了一个服务器应用程序,它在写入数据库/磁盘之前处理大量数据。我没有为所有内容创建临时文件,而是编写了一个内存缓存,这使得整个过程超级快。但记忆是有限的,所以我试图找出限制是什么。我想知道为什么我的小测试程序在恰好 1,000 MB 后抛出 OutOfMemoryException。

有帮助吗?

解决方案

Win32 进程的虚拟地址空间限制为 1.5GB(不完全正确)。此外,在 .NET 框架中,.NET 进程可以消耗的内存百分比有一个限制。machine.config 有一个 processModel 元素,其属性为 memoryLimit,它是进程可以消耗的可用内存的百分比。默认值为 60%。

如果您运行的机器有 2GB 内存,或者您没有在 BOOT.INI 中启用 /3GB 开关,那么每个进程将获得约 1.3GB 内存。

我找不到该知识库文章,但如果我没记错的话,无论您的设置如何,.NET 1.x 都无法寻址超出 1.5GB(1.8GB?)限制的地址。

http://blogs.msdn.com/tmarq/archive/2007/06/25/some-history-on-the-asp-net-cache-memory-limits.aspx http://social.msdn.microsoft.com/Forums/en-US/clr/thread/c50ea343-b41b-467d-a457-c5a735e4dfff http://www.guidanceshare.com/wiki/ASP.NET_1.1_Performance_Guidelines__-_Caching#Configure_the_Memory_Limit

其他提示

具有巨大块的记忆永远不是一个好主意,即使在64位.你得到很大的问题,连续的存储器和碎片。

这里的问题是找到一个毗连区块。你可以尝试启用模式3gb(可能帮助它找到更多的几个字节),但是我 真的 建议反对它。答案在这里是:

  • 使用较少的记忆
  • 使用一个数据库或文件系统
  • 使用64

你也可能会想读 埃里克利珀特的 博客(他似乎有一项对于每一个共同的。净的问题...)

我最近一直做在32位过程在.NET周围内存限制的广泛分析。我们大家都被这个想法轰炸,我们可以在.NET应用程序分配高达2.4GB(2 ^ 31),但不幸的是,这是不正确的:(。申请过程中有那么多的空间使用和操作系统做了伟大的作业管理对我们来说,然而,.NET本身似乎有自己的开销占约600-800MB为推动内存限制典型的现实世界的应用程序。这意味着,只要你分配一个整数数组大约需要1.4GB,你应该会看到一个OutOfMemoryException()。

显然,在64位,这个限制的方式发生以后(让我们在5年内:)聊天),但一切都在内存中的一般尺寸也随之增加,因为增加的字大小的(我发现这是〜1.7至〜2次)

我知道肯定是从操作系统的虚拟内存肯定的想法不给你一个进程内几乎是无止境的分配空间。它只是有使之充分2.4GB是可寻址的,以在同一时间运行的所有(多种)的应用程序。

我希望这有助于洞察有点。

我原来在这里回答有关的东西(我仍然是一个牛逼所以我不知道我是多么应该做这些链接):

是有一个存储器限制为单个.NET过程

你可以分配更多的存储于2GB通过建立应用程序的64位架构,这就需要创建一个新建立的结构在Visual Studio,并建立应用程序才会运行上的64位版本的Windows。中。净,使用默认"任何CPU"建立选择你的应用程序,我发现我只能分配大约1.5GB的记忆从堆(甚至64位Windows machine),这是因为应用程序实际上只是运行中的32位的模式时,它是建立在"任何CPU"模式。但是,通过汇编,64架构,可以分配更多的存储从堆在应用程序的执行,我将解释如何创建一个64建立你的应用程序如下:

再次,使用正常的(默认)"任何CPU"建立选择在你的.净项目,应用程序将一直运行的32位的方式,甚至在64位Windows操作系统。因此你不能分配超过大约1.5到2GB RAM存在的应用程序执行。运行,你的.网应用程序在真正的64位模式,将需要进入建立的配置管理,并创建一个建立类型的64架构,然后重新编译程序64明确使用,建设类型。该64建立模式的选择,可以创建。净的解决方案,采用以下步骤:

  1. 在这些工作室"的方案管"格,右击的解决方案图标和选择"的配置管理"选项,从行了菜单。这将打开建设"的配置管理"的对话的窗口。净解决方案文件。
  2. 在右边,顶侧建立"的配置管理"的对话,点击下箭和选择"<new>"选项。这将打开"新的解决方案平台"的对话。
  3. 在"新的解决方案平台"的对话,对于"平台"的选择,选择"64的"从下拉菜单。然后点击"确定"的按钮以及新的、64建立选择将现在可在配置管理的对话。
  4. 然后,在"配置管理"的对话中,选择"64的",在"活动方案平台"的下拉菜单。点击"关闭"。
  5. 在这些工作室"的方案管"格,右击CS项目标,并选择"属性"的选项,从行了菜单(最后的选择在这个菜单)。这将打开CS项目属性窗口。
  6. 在左侧的CS项目属性窗口,点击"建立"标签,以显示的建设性对于你的码的项目。在这个窗口的顶部,请注意"平台"现在应该说"64"(而不是默认的"任何CPU"option).如果"平台"下没有显示出"64的",你应该选择它。
  7. 然后就建立你的代码,并在"bin"文件夹,你现在应该有一个64的文件夹新的64位建立的程序内。

使用64位建立的应用程序上的64位Windows操作系统将允许您的程序来分配更多~2GB的存储器,大概是2^64地址空间(如果你的内存和盘空间可用,这是真实的限制因素,因为时间编写本响应)。

如果你仍然在运行的存在应用程序,也可以增加小的窗户内存页的文件。在窗户,该网页的文件允许的操作系统转移存储器从RAM盘,如果它运行的RAM的存储空间。但有一个很大的时间花费在转换的部分内存来和从盘,所以它可能是一个真正的打击上述性能的应用程序。不管的业绩,通过增加该页面尺寸,你可以(在理论上)使该页的文件大有免费的空间可用于C:驱动的你的windows的机器。在这种情况下,您的申请会能够分配,例如,最多4个结核病的存储器(或什么的存储量,你的网页的文件大小设)在执行期间你的计划。改变网页的文件设置你的Windows的机器,做到以下几点:

  1. 开放"系统性"对话通过正确的点击"这台电脑"和选择"属性"的选项,上弹出式菜单。这也可以完成在以后版本的Windows(Windows10,赢2012服务器等。)通过要"开始">"控制面板">"系统和安全">"系统"。
  2. 在左边的"系统"的对话,点击"高级系统属性"的选项。这将显示"高级"标签的遗留"系统性"的对话。
  3. 在"高级"标签的"系统性"的对话,点击"设置"按钮,在"绩效"的方框。这将打开"性选择"的对话。
  4. 在"性选择"的对话,点击"高级"标签看到目前的大小设置Windows存页的文件。
  5. 增加该页的文件大小,点击"改变"的按钮以及"虚拟存储器"的对话将会开放。
  6. 在"虚拟存储器"的对话中,选择"C:"驱动,然后在"定义的尺寸",设定"最初"和"最大"的大小。你可以使用任何大小到最大量的免费空间C:驱动的,但作出这一改变将储备的空间,页面上的文件的硬盘驱动器。
  7. 然后点击"Ok"上的所有对话提交新设置。然后重新启动电脑,以确保所有的更改已经被适当地完成,新的一页文件设置均在运作。

无论如何,我希望这可以帮助人们了解为什么他们可以跑到这个1.5-2GB存储器限制问题中的一个。网应用程序,即使在上运行的64位Windows的机器。这可能是一个非常令人困惑的问题对人类和我希望我的解释是有道理的。请随意的消息我问这个答案如果需要的话。

我觉得这里的问题是,这个应用程序将增加10MB每圈它使和循环是:“虽然(真)”,这意味着,直到应用程序被停止,将增加这些10MBs。所以,如果它是为100环,将增加了接近1GBs到RAM中运行,并且我假设它会在不到30秒已经这样做了。我的意思是你想的每个环路内存10兆名字节的,在永无止境的循环

我,如果我不明白你的意思真的很抱歉,但是:

static void Main(string[] args)
{
    ArrayList list = new ArrayList();
    int i = 0;
    while (true)
    {
        using(byte newBt = new byte[1024 * 1024 * 10])
        {
            list.Add(newBt); // 10 MB
            i += 10;
            Console.WriteLine(i);
        }
    }
}

您是否尝试过使用方法?这可能是一个愚蠢的问题,但你为什么要创建一个死循环? o如果尝试码带符号>。>的xD。

来源: http://msdn.microsoft的.com / EN-US /库/ yh598w02(v = VS.80)的.aspx

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top