Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 最大收集容量<;T>;与x86的预期不同_C#_.net - Fatal编程技术网

C# 最大收集容量<;T>;与x86的预期不同

C# 最大收集容量<;T>;与x86的预期不同,c#,.net,C#,.net,中的主要问题是关于集合(如列表)中可以包含的最大项数。我在这里寻找答案,但我不明白其中的道理 假设我们正在处理一个列表,其sizeof(int)=4字节。。。每个人似乎都确信,对于x64,您的最大值为268435456int,而对于x86,您的最大值为134217728int。链接: 然而,当我自己测试时,我发现x86的情况并非如此。有人能告诉我哪里可能是错的吗 //// Test engine set to `x86` for `default processor architect

中的主要问题是关于集合(如列表)中可以包含的最大项数。我在这里寻找答案,但我不明白其中的道理

假设我们正在处理一个
列表
,其
sizeof(int)
=4字节。。。每个人似乎都确信,对于x64,您的最大值为268435456
int
,而对于x86,您的最大值为134217728
int
。链接:

然而,当我自己测试时,我发现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"
    }
}
///对于“默认处理器体系结构”,测试引擎设置为“x86”`
[测试方法]
公共void TestMemory()
{
var x=新列表();
尝试
{
用于(长y=0;y
对于x64:268435456(预计)

对于x86:67108864(比预期少2倍)

为什么人们说一个包含134217728
int
的列表正好是512MB的内存。。。当您有134217728*sizeof(int)*8=4294967296=4GB时。。。每个进程超过2GB限制的方式是什么。 鉴于67108864*sizeof(int)*8=2147483648=2GB。。。这是有道理的

我在运行Windows7 8GB RAM的64位计算机上使用.NET4.5。在x64和x86中运行我的测试

编辑:当我直接将容量设置为
列表(134217728)
时,我得到一个
系统.outofmemory异常


EDIT2:我的计算错误:乘以8是错误的,实际上MB=/=Mbits。我在计算Mbits。但67108864英寸的数据量仅为256MB。。。这比预期的要小得多。

虽然您可以拥有MaxValue项,但实际上在此之前您将耗尽内存

以x86运行即使在x46设备上也能拥有最多4GB的ram,如果在x86版本的Windows上,则2GB或3GB是最大值


可用ram很可能要小得多,因为您只能为阵列分配最大的连续空间。

一个
列表
类的底层存储是一个
T[]
阵列。数组的一个硬要求是进程必须能够分配一个连续的内存块来存储数组

这是32位进程中的一个问题。虚拟内存用于代码和数据,您可以从它们之间留下的孔中进行分配。虽然一个32位进程将有2G的内存,但你永远也无法接近这个大小的洞。启动程序后,地址空间中最大的漏洞大约是500或600兆字节。这在很大程度上取决于DLL加载到进程中的内容。不仅是CLR、抖动和框架程序集的本机映像,还有与托管代码无关的映像。比如反恶意软件和大量“有用”的实用程序,它们会将自己蠕虫式地植入每个进程,比如Dropbox和shell扩展。一个基础差的可以把一个漂亮的大洞切成两个小洞

随着程序分配和释放内存一段时间,这些漏洞也会变小。一个称为地址空间碎片的一般问题。一个长时间运行的进程可能会在90 MB的分配上失败,即使周围有大量未使用的内存


您可以使用SysInternals来获得更多的洞察力。Russinovich的《Windows内部构件》一书的副本对于理解您看到的内容通常也是必要的。

这可能也会有所帮助,但我能够通过使用提供的代码创建一个测试项目来复制这一限制

在控制台、winform、wpf中,我能够获得
134217728
限制

在asp.net中,我得到了
33554432
limit


因此,在您的一条评论中,您提到了
[TestMethod]
,这似乎就是问题所在。

有多少ram以及windows的哪个版本?您是否尝试过预先设置列表容量?类似这样:
var x=新列表(134217728)。请记住,内部阵列是通过重新分配一个新阵列来扩展的。。。这可能会破坏内存分配。不过,这只是一个线索,我远不是一个专家。还有,为什么在最后的两次计算中,你要将每个数量乘以8?为什么你要将大小乘以8?如果希望生成字节,则不需要这样做。所以x64上的列表大小正好是512MB@LeandroTaset不幸的是,当我直接设置容量时,我得到了一个
System.OutOfMemoryException
。这应该是意料之中的,因为我们超过了2GB的内存限制。@OleksandrPshenychnyy很好,你是对的,我添加了一个编辑。+1-查看内存映射是理解这个问题的正确方法。回答得很好。我确保我没有加载任何额外的DLL,并且确保除了代码之外没有其他任何东西正在执行。。。看起来测试引擎中有一些额外的东西。现在,最大容量指示为134217728
int
。非常感谢,这是有道理的。事实上,这似乎确实是个问题。汉斯的回答也让我得出了这个结论。