2010-04-19 35 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();