我有非常大的 DataTable 对象、非常大的数组等的应用程序。
目前我的内存使用量低于 2GB。
当我的应用程序在 32 位系统上生成 4 个大小为 1GB 的数组时会发生什么?
它会崩溃吗?
我知道 CLR 中的 2GB 对象大小限制,但是很多大对象呢?
我试图测试它,我声明了几个大数组,但是当它们为空时,它们似乎不使用 RAM。我没有尝试填写它们,我决定在这里问。
64 位应用程序,包括托管应用程序,可以访问大内存。
32 位应用程序具有最大 4GB 的虚拟地址空间。在实践中,他们默认获得 2GB。/LARGEADRESSAWARE
应用程序可以通过 boot.ini 中的 /3gb 获得 3GB 或在 WoW64 上运行时获得 4GB。
托管应用程序,即使在 x64 上也无法分配任何大于 2GB 的单个对象。包括数组。
但无论您可以使用多少 VA:操作一个 +2GB 的DataTable对象是行不通的。使用能够快速处理和操作大量数据并能够智能分页的存储引擎。Redis、Cassandra甚至传统的 RDBMS 更适合这项工作。
即使您决定直接在内存中操作数据,您也需要一种比DataTable
.
所有 32 位应用程序都限制为2GB 内存*。因此,无论您如何分配 RAM,您都将用完 2GB。
如果你需要更多,你需要在 64 位系统上运行它并为 64 位编译它。
如果您使用的 RAM 超出了您可以处理(或拥有)的数量,则会出现System.OutOfMemoryException
异常。试试这段代码看看:
List<byte[]> foo = new List<byte[]>();
for (int i = 0; i < 10000; ++i )
foo.Add(new byte[1024*1024*1024]);
是的,它会崩溃。这是我尝试过的示例代码:
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
。
与之相反的领域当然不能被遗漏。因此,无论编译器是否优化了代码,第一个示例都会崩溃。
有关不同操作系统的物理内存限制,请参阅这篇文章Windows 版本的内存限制。
但是,可以将运行为 32 位的 .NET 应用程序的限制从 2GB 增加到最高 3GB。为此,您必须editbin /LARGEADDRESSAWARE
在可执行文件上运行。您可以在此处找到有关它的更多详细信息: