4

我有非常大的 DataTable 对象、非常大的数组等的应用程序。

目前我的内存使用量低于 2GB。

当我的应用程序在 32 位系统上生成 4 个大小为 1GB 的数组时会发生什么?

它会崩溃吗?

我知道 CLR 中的 2GB 对象大小限制,但是很多大对象呢?

我试图测试它,我声明了几个大数组,但是当它们为空时,它们似乎不使用 RAM。我没有尝试填写它们,我决定在这里问。

4

5 回答 5

6

64 位应用程序,包括托管应用程序,可以访问大内存。

32 位应用程序具有最大 4GB 的虚拟地址空间。在实践中,他们默认获得 2GB。/LARGEADRESSAWARE应用程序可以通过 boot.ini 中的 /3gb 获得 3GB 或在 WoW64 上运行时获得 4GB。

托管应用程序,即使在 x64 上也无法分配任何大于 2GB 的单个对象。包括数组。

但无论您可以使用多少 VA:操作一个 +2GB 的DataTable对象是行不通的。使用能够快速处理和操作大量数据并能够智能分页的存储引擎。RedisCassandra甚至传统的 RDBMS 更适合这项工作。

即使决定直接在内存中操作数据,您也需要一种比DataTable.

于 2013-04-25T12:44:43.940 回答
4

所有 32 位应用程序都限制为2GB 内存*。因此,无论您如何分配 RAM,您都将用完 2GB。

如果你需要更多,你需要在 64 位系统上运行它并为 64 位编译它。

  • 使用LARGEADDRESSAWARE 32 位应用程序最多可以使用 3GB 内存,感谢 Marc Gravell 在评论中提醒我这一点。
于 2013-04-25T12:39:18.693 回答
1

如果您使用的 RAM 超出了您可以处理(或拥有)的数量,则会出现System.OutOfMemoryException异常。试试这段代码看看:

        List<byte[]> foo = new List<byte[]>();
        for (int i = 0; i < 10000; ++i )
            foo.Add(new byte[1024*1024*1024]);
于 2013-04-25T12:41:02.890 回答
1

是的,它会崩溃。这是我尝试过的示例代码:

class Program
{
    static byte[] arr = new byte[1024 * 1024 * 1024];
    static byte[] arr2 = new byte[1024 * 1024 * 1024];
    static byte[] arr3 = new byte[1024 * 1024 * 1024];
    static byte[] arr4 = new byte[1024 * 1024 * 1024];
    static void Main(string[] args)
    {            
        Console.ReadKey();
    }
}

这是一个相当原始的测试程序。除非可以立即访问全部数据量,否则它可能已经被 GC 部分回收,因此不会崩溃。

您也可以将它们设为本地。但是,如果您进行发布构建(带有代码优化),则以下位就像一个 charm,因为未使用的数组(或通常的变量)可能会被优化掉:

static void Main(string[] args)
{
    byte[] arr = new byte[1024 * 1024 * 1024];
    byte[] arr2 = new byte[1024 * 1024 * 1024];
    byte[] arr3 = new byte[1024 * 1024 * 1024];
    byte[] arr4 = new byte[1024 * 1024 * 1024];
    Console.ReadKey();
}

调试构建(无代码优化)中,上述位也崩溃了OutOfMemoryException

与之相反的领域当然不能被遗漏。因此,无论编译器是否优化了代码,第一个示例都会崩溃。

于 2013-04-25T12:42:22.340 回答
0

有关不同操作系统的物理内存限制,请参阅这篇文章Windows 版本的内存限制

但是,可以将运行为 32 位的 .NET 应用程序的限制从 2GB 增加到最高 3GB。为此,您必须editbin /LARGEADDRESSAWARE在可执行文件上运行。您可以在此处找到有关它的更多详细信息:

于 2013-04-25T12:49:54.003 回答