2010-04-19 34 views
3

有没有办法告诉.NET在第2代堆中分配新对象。我有一个问题,我需要分配大约200 MB的对象,对它们做些什么,然后把它们扔掉。这里发生的是所有的数据被复制两次(从gen0到gen1,然后从gen1到gen2)。.NET对象创建和世代

回答

0

框架的工作方式与使用普通对象的大对象不同。所以简单地说,它将大对象放入代中,并且在重新分配堆时不要移动它。

2

在第二代中没有办法直接进行分配。所有的分配都发生在第0代,对于LOH上的大型对象。

但是,当对象移动到新一代时,通常不会复制数据。而是移动不同堆的起点。由于堆的压缩,物体可能会移动,但这是一个不同的故事。

如果在第2代中存储对象很重要,则可以重新使用这些实例。即对类型做一些init方法并调用它,而不是创建新的实例。

+0

如果我理解正确的,所有新创建的对象是在GEN0堆中分配。当gen0堆已满时,所有对象(仍然需要的)都被移至gen1,gen0变为空。当Gen1的GC运行时,gen1也会发生同样的情况。据我所知,没有这样的东西来移动指针到不同的堆。也许你可以给MSDN或其他地方的链接,因为我遇到的是很多复制(可以看到性能监视器)。 – nimoraca 2010-04-19 09:18:07

+0

@nimoraca:移动指针部分是CLR所做的。如果没有,你将不得不为所有收集物品移动物体,这将是非常低效的。详情请参阅C#书CLR。这篇文章有一些相同的点http://msdn.microsoft.com/en-us/magazine/bb985010.aspx – 2010-04-19 09:48:18

+0

@nimoraca:如果你对细节感兴趣,你也可以使用WinDbg检查不同的堆等和SOS(或PSSCOR2)。 – 2010-04-19 09:49:37

0

如果您想修复您的对象,使框架无法移动它们,您可以尝试使用GCHandle来固定对象。这通常用于P/Invoke,但会给出您要查找的结果。我怀疑你会因代际压缩而看到减速,但我不能说没有看到你的分析数据。

http://msdn.microsoft.com/en-us/library/khk3k17t%28v=VS.71%29.aspx

例子:

var q = new MyObject(); 
var handle = GCHandle.Alloc(q, GCHandleType.Pinned); 

// use object 

handle.Free();