2010-05-06 12 views
0

使用CLR探查一些experimenation後,我發現:如何知道.NET中的大對象堆(LOH)中分配了一個結構數組?

Node[,] n = new Node[100,23]; //'84,028 bytes, is not placed in LOH 
Node[,] n = new Node[100,24]; //'86,428 bytes, is 

    public struct Node { 
     public int Value; 
     public Point Point; 
     public Color Color; 
     public bool Handled; 
     public Object Tag; 
    } 

在運行時,我怎麼知道的結構(或陣列)的陣列中的大對象堆(LOH)被分配?

+0

我不相信這是可能的(不使用自己的剖析API)。你爲什麼想知道? – 2010-05-06 00:28:43

+0

我遇到了應用程序使用的一個結構的性能問題。我已經成功地優化了其他數組(http://stackoverflow.com/questions/2762424/what-is-the-fastest-way-to-initialize-a-multi-dimensional-array-to-non-default-va/) 。然而,這種結構是真正的性能殺手。 – AMissico 2010-05-06 00:33:00

+0

如果只是爲了性能調整,那麼爲什麼不直接使用profiler? – 2010-05-06 00:37:14

回答

2

大於85,000字節的任何對象都將存儲在LOH中。這裏有一篇關於.Net Memory Management的好博客文章。

+0

for double []當前的限制(.NET RT 4.0)爲8k – user492238 2011-01-28 09:56:20

1

從您的意見,我不認爲你實際上需要知道對象是否會去蕙。無論這是否是應用程序放慢的真正原因,當您真正想要做的是在用戶輸入「太大」的值時向用戶顯示警告。

所以我會提出一些更簡單的建議:只需使用一點點試錯來確定截止值。如果他們輸入的尺寸超過了試錯值,則顯示警告。

至於你的實際性能問題,不要分配一個大的二維數組,你可以簡單地分配一堆「小」一維數組。相反的:

Node[,] n = new Node[100,100]; // this will go the LOH 

你可以這樣做:

Node[][] n = new Node[100][]; 
for(int i = 0; i < n.Length; i++) { 
    n[i] = new Node[100]; // none of these will be on the LOH 
} 

你最好還是有相同數量的總節,但不會有事的LOH。就我個人而言,我認爲你可能會發現,表現實際上並沒有那麼大的不同,但只是試一試也許是值得的。

1

你可以在分配之後找到正確的。使用GC.GetGeneration(對象)超載來獲取生成編號,對象在規定對於LOH,這將是2

Node[,] n = new Node[100,23]; 
// GC.GetGeneration(n) should give 0 
Node[,] n = new Node[100,24]; 
// GC.GetGeneration(n) should give 2 

注意,這有一些限制,是絕非有道生產代碼,我假設:如果稍後查詢該編號,則該對象可能已經從第0代移至第2代。我不知道區分Gen2(小對象)堆和LOH。而且,對於我測試過的所有.NET版本,爲LOH上的對象返回的數字爲2。但我無法在真實的規格中找到這個,所以它也可能是一個變化的問題。

+0

+1創新思維。尼斯。聰明。我應該想到的東西。稍後我會試一試。 – AMissico 2011-01-27 17:37:53

+0

@AMISSico:謝謝!很高興知道,你喜歡它(即使+1沒有到達)) – user492238 2011-01-28 09:57:22

+0

@ user492238:當我驗證您的答案時,您將獲得實際的投票。 :O) – AMissico 2011-01-28 17:25:08

相關問題