好的,所以在我的一个项目中,我试图重新制作存储某些变量的方式,我有一个简单的对象数组。这些对象引用的类是:
class Blocks
{
public byte type = Block.Empty;
byte lastblock = Block.Zero;
}
我计划向它添加更多内容,在当前类类型中是对象的当前值,而lastblock是对象的用途。
我像这样创建数组:
blocks = new Blocks[width * depth * length];
for (int i = 0; i < ((width * length) * depth); i++)
{
blocks[i] = new Blocks();
}
我遇到的问题是,当我创建一个非常大的数组(512,512,512或134217728,对于那些不喜欢数学的人)时,数组变得非常大,超过3.5演出。
创建这个数组的旧方法有点简单,但扩展起来要困难得多,它简单地创建了一个表示当前块的字节数组,并且在实际加载时似乎只使用了2兆的ram(我的不要,因为134217728字节应该在134兆左右......对吗?)。令我感到困惑的是,对象引用可以产生更多的内存使用。
我做错了什么,或者我应该回到原来的方式?我希望对象引用只是因为它意味着我的所有变量都在1个数组中,而不是在4个独立的数组中,似乎就好像它对系统更好。
编辑:
经过几种不同的方式,我发现改变了
class Blocks
到
struct Blocks
创造了一个与众不同的世界,感谢社区提供未来使用的欢迎提示,遗憾的是我不想在结构中添加两个字节并将其调用完成,这就是我停下来测试我的设计和伤口的地方原来的问题。在结构中添加任何其他内容之后(至少在我的列表中的任何其他内容,意味着播放器对象引用或播放器名称字符串。)它会导致内存不足异常,这意味着我将无法毕竟使用这个系统。
但是如何做到这一点的知识将来会非常有用。为此,再次感谢你。
答案 0 :(得分:4)
以下是我尝试使用结构类型而不是类类型:
public struct Block
{
public byte _current;
public byte _last;
}
public static void RunSnippet()
{
Block[] blocks = new Block[512 * 512 * 512];
for (int i = 0; i < ((512 * 512) * 512); i++)
{
blocks[i] = new Block();
}
}
该片段几乎立即运行,并且吃了大约267 Mb的RAM。
如果可能,请尝试 struct 。
答案 1 :(得分:1)
您可以使用List类来管理无限数量的对象。请查看我提供的链接。您可以将无限(理论上)理想数量的对象添加到列表中。
使用列表,您可以轻松地按索引访问任何项目。它还具有搜索,排序和操作其中包含的对象的方法。
如果您使用列表,您的代码将看起来如下 -
List<Blocks> blocks = new List<Blocks>();
for (int i = 0; i < ((width * length) * depth); i++) // The amount of items that you want to add
{
Blocks b = new Blocks();
blocks.Add(b);
}
您可以按如下方式访问此列表中的每个项目 -
foreach(Blocks b in blocks)
{
// You have the object, do whatever you want
}
您可以找到列表中包含的对象的任何特定索引。请参阅此method example。
因此,使用列表,您将能够以统一的方式轻松管理大量对象。
要了解详情,请转到here。
答案 2 :(得分:0)
请阅读:Object Overhead: The Hidden .NET Memory Allocation Cost。
您的对象的总成本类似于16个字节(在32位系统上)。 (“标题”为8个字节,字段为4个字节,参考为4个字节)和512 * 512 * 512 * 16 = 2.1gb
: - )
但你可能是64位系统,所以它是16 + 8 + 8 = 28,所以4.29gb
。
答案 3 :(得分:0)
您应该考虑使用“struct”而不是“class”。
http://msdn.microsoft.com/en-us/library/ah19swz4(v=vs.71).aspx
“结构类型适用于表示轻量级对象,如Point,Rectangle和Color。尽管可以将点表示为类,但在某些情况下结构更有效。例如,如果声明了1000个Point对象的数组,你将为引用每个对象分配额外的内存。在这种情况下,结构更便宜。“
如果您尝试,请发布您的搜索结果。
答案 4 :(得分:0)
创建数组时,还要在每个单元格上实例化一个块。你真的需要这样做吗?
blocks[i] = new Blocks()
;
如果不实例化Blocks,则只需要一个空引用数组。在访问代码中,您可以检查null并返回默认值。这些方面的东西:
if(blocks[i,j] == null) return new Blocks();
else return blocks[i,j];
写入时还要检查是否有,如果没有,请先创建它。这应该可以节省大量内存。
使用锯齿状数组或嵌套列表也应该有很多帮助。
关心GJ
答案 5 :(得分:0)
结构是前进的方向,并且会开启使用不安全的代码/指针算法进行优化的可能性
struct Block
{
byte Current;
byte Last;
}
Block[] blocks = new Block[512 * 512 * 512];
unsafe
{
Block* currentBlock = &blocks;
for (int i = 0; i < (512 * 512) * 512; i++)
{
currentBlock->Current = 0xff;
currentBlock->Last = 0x00;
currentBlock++;
}
}
当然有人会来,说可变的结构是邪恶的! (只有你不知道如何使用它们)