Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.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# 如何在Array.Resize期间防止OutOfMemory异常?_C#_Arrays_Xna_Out Of Memory - Fatal编程技术网

C# 如何在Array.Resize期间防止OutOfMemory异常?

C# 如何在Array.Resize期间防止OutOfMemory异常?,c#,arrays,xna,out-of-memory,C#,Arrays,Xna,Out Of Memory,我当前的项目包括一个植被模拟,能够渲染大量随时间增长和复制的实例树模型 我目前在这行代码中得到了一致的OutOfMemory异常 if (treeInstances.Length <= currentIndex) Array.Resize(ref treeInstances, currentIndex + 500); if(treeinstancess.LengthC#设计用于处理小内存分配,比处理大内存分配要好得多。当您执行数组.Resize时,您强制分配新内存块,复制的数据然

我当前的项目包括一个植被模拟,能够渲染大量随时间增长和复制的实例树模型

我目前在这行代码中得到了一致的OutOfMemory异常

if (treeInstances.Length <= currentIndex)
    Array.Resize(ref treeInstances, currentIndex + 500);
if(treeinstancess.LengthC#设计用于处理小内存分配,比处理大内存分配要好得多。当您执行数组.Resize时,您强制分配新内存块,复制的数据然后旧内存块将失效。这是一种非常有效的分割堆的算法:-)

如果一开始就知道阵列需要多大,请将阵列设置为该大小。如果您不喜欢,我建议您使用List或类似的类。该类基于每个项目进行分配

我被纠正了,谢谢你们让我诚实。我太习惯于处理类而不是结构。我应该更清醒些


如果TreeInstance被更改为一个类,那么列表将变为一个地址数组,TreeInstance的地址可以/将被分配到更小的块中。更新所有TreeInstance需要一些代码更改。

看起来我找到了问题的答案,在Dweeberly描述我的
Array.Resize()
系统是“分割堆的非常有效的算法”之后。这是我的一个概念化问题:我不明白内存不足异常可能是由于没有足够的连续内存造成的,而是假设由于垃圾收集没有捕获数组,我达到了某种限制

Eric Lippert的这篇博文让我直截了当:

对于处理内存不足异常的任何人,或者作为游戏编程的一般知识,都值得一读

简单的回答是:在一个为32位窗口编译的程序中,重复分配然后删除大型对象,就像我通过
Array.Resize()
所做的那样,可以将地址空间分割为与分配的对象一样大的空空间的“块”。随后,尝试分配一个大于这些空闲块的对象将抛出内存不足异常,即使您的累积内存要大得多


正如上面所建议的那样,适当的反应只是避免重复调整数组的大小:我只需要理解为什么。在我的例子中,这意味着重新编写实例化模型方法,以便只绘制较大数组的子集,而不是整个数组。在那之后,这是一种简单的方法,可以分配一个比我在初始化过程中需要的大得多的数组。

为什么要分配自己的数组?你考虑过使用列表吗?根据所涉及的阵列大小,+500分配可能不是扩展阵列的最有效方法。它们可能最终会在大型对象堆上留下洞。我的建议是尽可能使用列表。如果你不使用内存分析器,看看是什么占用了内存。考虑到你的结构中有20个浮点数,数组中有3000-5000个元素,你肯定会在大对象堆上结束。一种策略是预先分配足够大的数组。我使用自己的数组,因为实例化绘制方法将数组作为参数,直接分配数组似乎比每秒调用List.ToArray()60次更好。不过,在这个阶段我不能肯定。错<代码>列表
由单个数组支持。您是否意识到
列表
使用数组作为其底层存储机制?它也不会为每个项分配空间,它会分配一个新数组,其大小是当前基础数组的两倍,并在空间不足时将当前数组复制到该数组中。