【发布时间】:2014-04-02 16:10:16
【问题描述】:
关于集合(例如 List)中可以包含的最大项目数的主要问题。我在这里寻找答案,但我不明白其中的原因。
假设我们正在使用List<int> 和sizeof(int) = 4 字节...每个人似乎都确信对于x64,您最多可以有268,435,456 int,对于x86,最多可以有134,217,728 int。链接:
- List size limitation in C#
- Where is the maximum capacity of a C# Collection<T> defined?
- What's the max items in a List<T>?
但是,当我自己对此进行测试时,我发现 x86 并非如此。谁能指出我可能错的地方?
//// Test engine set to `x86` for `default processor architecture`
[TestMethod]
public void TestMemory()
{
var x = new List<int>();
try
{
for (long y = 0; y < long.MaxValue; y++)
x.Add(0);
}
catch (Exception)
{
System.Diagnostics.Debug.WriteLine("Actual capacity (int): " + x.Count);
System.Diagnostics.Debug.WriteLine("Size of objects: " + System.Runtime.InteropServices.Marshal.SizeOf(x.First().GetType())); //// This gives us "4"
}
}
对于 x64:268435456(预期)
对于 x86:67108864(比预期少 2 倍)
为什么人们说包含 134217728 int 的 List 正好是 512MB 内存...当您有 134217728 * sizeof(int) * 8 = 4,294,967,296 = 4GB... 什么是超过 2GB 的限制每个进程。
而 67108864 * sizeof(int) * 8 = 2,147,483,648 = 2GB... 这是有道理的。
我在运行 Windows 7 8GB RAM 的 64 位机器上使用 .NET 4.5。在 x64 和 x86 中运行我的测试。
编辑:当我将容量直接设置为List<int>(134217728) 时,我得到一个System.OutOfMemoryException。
EDIT2:我的计算错误:乘以 8 是错误的,实际上是 MB =/= Mbits。我正在计算 Mbits。 67108864 个整数仍然只有 256MB...这比预期的要小。
【问题讨论】:
-
多少内存和哪个版本的windows?
-
您是否尝试过预先设置列表容量?像这样:
var x = new List<int>(134217728);。请记住,内部数组是通过重新分配一个新数组来扩展的……这可能会破坏内存分配。不过,这只是一个线索,我远非专家。另外,你为什么在你的最终计算中将每个数量都乘以 8? -
为什么要将大小乘以 8?如果你想以字节为单位,你不需要那个。所以 x64 上的列表大小正好是 512 MB
-
@LeandroTaset 不幸的是,当我直接设置容量时,我得到一个
System.OutOfMemoryException。这应该是意料之中的,因为我们超过了 2GB 内存限制。 -
@OleksandrPshenychnyy 好地方,你是对的,我添加了一个编辑。