.Net数组大小的限制是什么?

27

我听说在.Net中 Array 的大小有一个硬性限制。据说无论是int[]double[]还是你自己的数组对象,任何单个实例可以分配的最大内存量为2GB,即使你使用的是64位机器,这个2GB的限制仍然存在。

我不确定我的印象是否正确,有人能确认吗?


哇,你开始了一个有趣的讨论。 - uriDium
如果这能让你感觉好一点:2GB的限制也适用于非托管代码。这是x64指令集中的一个限制,索引偏移寻址仍然有32位的偏移限制。并不是说不能克服这个问题,只是这样做非常低效。 - Hans Passant
1
Hans Passant:我在我的x64应用程序中使用C++非托管代码,使用malloc分配了一个600E6 double数组。这是4.8E9字节。 - Michael Fitzpatrick
6个回答

24

在.NET 4.5版本之前,最大对象大小为2GB。从4.5版本开始,如果启用了gcAllowVeryLargeObjects,则可以分配更大的对象。请注意,string的限制不受影响,但是“arrays”应该也包括“lists”,因为lists是由arrays支持的。


感谢@Mark Gravell。我们记得这是一件事,但忘记了它的名称。 - lightw8

14

1
数组中的元素数量是否也有限制? - uriDium
1
@uriDium:是的,因为数组是一个对象。 - Brian Rasmussen
这个问题在.NET中关于数组大小有额外的信息。https://dev59.com/JHI-5IYBdhLWcg3w99oH#1589759 - Brian Rasmussen
嗨,我指的不是内存,而是数组可以容纳多少元素。但是我想也许它可以容纳的元素数量首先受到内存限制,而不是索引是整数值的事实? - uriDium
1
@Brain,我刚刚算了一下,我知道在Java中最小的类大小为8字节。在8字节的情况下,2147483648几乎是17GB。所以我猜我们甚至不会遇到索引作为整数的问题。然而... - uriDium
6
自 .NET 4.5 开始,此限制已被取消:http://msdn.microsoft.com/zh-cn/library/hh285054(v=vs.110).aspx。 - jhclark

4
您首先会遇到一个实际的限制 - 分配一个2GB的数组是非常困难的。我遇到的实际限制在程序开始时约为800MB,之后急剧下降。
大于64MB的任何内容在32位上都是一场赌博 - 大对象堆不会被碎片整理,因此您需要有65MB的连续空间,否则分配将失败。
理论上的限制包括:
- 可用内存,特别是在32位系统下。 - 32位数字索引空间(从0开始 - 数组不能使用负数,除非您在创建时聪明地操作)。您可以创建允许负数的数组,但不能使用C#标准语法 - 只能使用反射。 - 每个对象最多2GB。
但是,实际影响更大。
对于.NET 4.0...请考虑使用内存映射文件 ;)

1

我本以为限制可能在索引上。我认为所使用的索引必须是整数,因此除非它们有某种方法绕过这一点,否则任何大于整数的东西都行不通。这将是4294967296个元素。不确定这是否甚至半真半假。我想知道答案。

编辑: 正如tomtom指出的那样,除非他们使用了一个无符号整数,否则整数通常是带符号的。所以4294967296的一半大约是2147483648。


@TomTom:不是这样的。每个数组都是一个对象,由于对象被限制在2 GB内,因此取决于数组所包含的元素类型。 - Brian Rasmussen
1
@uriDium:2 GB 的限制将会显著地限制这个数字。你不能在一个数组中拥有 2147483648 个元素。 - Brian Rasmussen
@Brian Rasmussen:如果每个元素的长度为1字节,那么2147483648是理论上的最大元素数量。 - Aurril
@Aurril:你说得对,我应该说明在大多数情况下,2 GB 会限制元素的数量。Byte[] 可以接近理论最大值,但由于数组存储了一些额外的数据,所以它略小于理论最大值。 - Brian Rasmussen
CLI规范允许数组索引为“int”或“long”。微软选择在.NET中将它们限制为“int”,但Mono使用“long”,因为Mono广泛用于科学高性能集群计算,并且经常处理超过20亿个元素的数组。 - Jörg W Mittag
显示剩余2条评论

1
自从.NET 6以来,数组可以容纳的最大元素数量由Array.MaxLength定义。目前它是0x7FFFFFC7
虽然字符串类似于数组,但它们有一个更低的限制。目前你可以创建的最长字符串是0x3FFFFFDF

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接