【发布时间】:2009-04-23 09:45:53
【问题描述】:
在添加到 C# 列表时明确检查/处理您没有达到 2^31 - 1 (?) 的最大条目数是疯狂的,是真是假?
(假设这是一个平均列表大小小于 100 的应用。)
【问题讨论】:
在添加到 C# 列表时明确检查/处理您没有达到 2^31 - 1 (?) 的最大条目数是疯狂的,是真是假?
(假设这是一个平均列表大小小于 100 的应用。)
【问题讨论】:
1.内存限制
嗯,没有任何属性的 System.Object 的大小是 8 字节(2x32 位指针),或 64 位系统中的 16 字节。 [编辑:]其实我刚签入WinDbg,大小在x86(32位)上是12bytes。
因此,在 32 位系统中,您需要 24Gb 内存(在 32 位系统上无法拥有)。
2。程序设计
我坚信如此大的列表不应该保存在内存中,而应该保存在其他一些存储介质中。但在这种情况下,您将始终可以选择创建一个包装 List 的 cached 类,该类将在后台处理实际存储。因此,在添加之前测试大小是错误的测试位置,如果有一天您发现有必要,您的 List 实现应该自己做。
3.为了安全起见
为什么不在每个方法中添加一个重入计数器来防止堆栈溢出? :)
所以,是的,为此进行测试太疯狂了。 :)
【讨论】:
似乎过分了。根据列表中对象的大小,您不会先达到机器的内存限制吗? (我假设这个检查是由 List 类的用户执行的,在实现中没有任何检查?)
也许同事们都在提前考虑,这让人放心? (讽刺!)
【讨论】:
看起来是这样,我可能不会包括支票,但我对此感到矛盾。程序员曾经认为 2 位数字足以在日期字段中表示年份,理由是这对于他们的代码的预期寿命来说很好,但是我们发现这个假设是不正确的。
查看风险,查看努力并做出判断(也称为有根据的猜测!:-))。我不会说这有什么硬性规定。
【讨论】:
正如上面的答案一样,我怀疑会出现更多问题而不是担心。但是,如果你有时间和意愿,你可以打磨代码直到它发光!
【讨论】:
是的
(好吧,你问的是真还是假..)
【讨论】:
刚刚试过这段代码:
List<int> list = new List<int>();
while (true) list.Add(1);
我遇到了 System.OutOfMemoryException。那么你会怎么做来检查/处理这个?
【讨论】:
如果您继续向列表中添加项目,那么在您达到该限制之前很久就会耗尽内存。我所说的“长”实际上是指“比你想象的要快得多”。
请参阅大对象堆 (LOB) 上的 this discussion。一旦你达到了大约 21500 个元素(在 64 位系统上只有一半)(假设你正在存储对象引用),你的列表将开始成为一个大对象。由于 LOB 的压缩方式与普通 .NET 堆不同,因此您最终会将其碎片化到无法分配足够大的连续内存区域的程度。
因此您根本不必检查该限制,这不是真正的限制。
【讨论】:
是的,这太疯狂了。
考虑当您开始达到这些数字时,其余代码会发生什么。如果列表中有数百万个项目,该应用程序是否可用?
如果应用程序甚至有可能达到这样的数据量,也许您应该采取措施来防止列表变得那么大。也许您甚至不应该一次将所有数据保存在内存中。我真的无法想象任何代码都可以实际使用这么多数据的场景。
【讨论】: