Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.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>;内存不足异常,但远离2Gb限制_C#_.net_Out Of Memory - Fatal编程技术网

C#列表<;T>;内存不足异常,但远离2Gb限制

C#列表<;T>;内存不足异常,但远离2Gb限制,c#,.net,out-of-memory,C#,.net,Out Of Memory,我有一个列表,其中Matrix4是一个包含16个浮点数的结构,因此它使用16*4字节=64字节 当我开始向列表中添加项目时,当我越过100万行时,它会抛出内存不足异常 我知道.NET对每个对象有2Gb的限制,但除非我完全疯了: 1.000.000*64字节=~61mb 甚至还没有接近极限 根据task manager,当我开始填充列表时,我的应用程序使用的是896mb,当我到达异常时,它使用的是1028mb 这台计算机有8GB的物理内存,但只使用6Gb 关于为什么会发生这种情况有什么线索吗 --

我有一个
列表
,其中
Matrix4
是一个包含16个浮点数的结构,因此它使用16*4字节=64字节

当我开始向列表中添加项目时,当我越过100万行时,它会抛出内存不足异常

我知道.NET对每个对象有2Gb的限制,但除非我完全疯了:

1.000.000*64字节=~61mb

甚至还没有接近极限

根据task manager,当我开始填充列表时,我的应用程序使用的是896mb,当我到达异常时,它使用的是1028mb

这台计算机有8GB的物理内存,但只使用6Gb

关于为什么会发生这种情况有什么线索吗

---更新----

将平台目标更改为x64解决了单独测试项目中的问题。不幸的是,原始项目不能是x64,因为引用的x86 DLL不能在x64上工作。但这是另一个问题


我没有想到要把它改成x64,因为它似乎离内存限制很远,但我猜Hans Passant在122mb上说得对,离1.3Gb的限制太近了。谢谢大家。

大型结构是在大型对象堆(LOH)上完成的,这会导致碎片化

因此,虽然您可能有足够的空闲内存,但可能没有足够大的内存块

你的数字(1Mx64)本身是不够的,只有有足够的其他分配才能解释这个问题。您可以尝试解决这个特定的问题,但这可能只是一个更大的问题变得明显的点

通常,TaskManager不是诊断内存问题的正确工具。你需要一个内存分析器来找出发生了什么


它还取决于平台的版本以及是32位还是64位

这不是答案,但你不能像那样计算.NET内存分配。@RicardoSilva:
Matrix4
是一个结构,
float
也是一个结构。这两个都不是目标。你能发布一个简短但完整的程序来演示这个问题吗?达到1000万我没有任何问题…@RicardoSilva所有类型(除了指针)都可以隐式转换为对象。这并不意味着它们是对象。要将值类型转换为
对象
,装箱操作是必要的,尽管所有值类型确实都可以装箱为对象。简单而常见的解释是,您强制程序以32位模式运行。.NET项目的默认设置。所以你所有的优秀硬件基本上都没有使用过。一旦达到1028MB,就有可能解决空间碎片问题,GC需要找到一个可以容纳122MB的漏洞。在程序运行一段时间后,它往往会随机失败。通过使用List.Capacity属性和消除抖动强制来改进结果。这里的大型结构是什么?是否
Matrix4
太小而不能放在LOH上?@Asad-是的,但它们是值类型,因此列表将容纳Nx64字节的数组。使用大型N.Ah,即使单个大型对象也可以在LOH中分块分配(因此会导致碎片问题)?@Asad No,问题在于
列表的备份数组不断被重新创建,并且随着新项目的添加,项目被复制以增加其大小。创建这些大型数组会使内存碎片化。@这是正确的,但LOH的压缩频率远远低于主堆,因此所有现在已死亡的数组仍然可以将其碎片化。还请注意,在一段时间内,当需要一个新的备份阵列时,实际上同时需要两个阵列,直到它可以将项目从旧阵列复制到新阵列为止。