2012-01-23 210 views
1

我剛剛開始研究一個項目(我不是新項目),因爲性能優化會將32GB圖形數據(節點,邊等)加載到內存中並保留在內存中。這是一項長期運行的服務,因此數據意味着在服務的整個生命週期內保留在內存中。當CLR觸發Gen 2採集時,會有大量暫停(當然),從而影響性能,而GC則會掃描Gen 2,將所有事件都標記爲可訪問對象。導致性能問題的GC暫停

我想知道的是,有哪些策略可用於託管應用程序,它們必須將大量數據保存在內存中?什麼是防止第二代集合運行的最佳方式 - 曾經?

+0

如果你從未運行第二代,你會泄漏使它成爲第二代的物體,但它們不會永遠活着。根據你的應用程序的作用,這可能是很多對象。 – delnan

+0

對不起,你是對的。但是有沒有可以防止這種長時間停頓的策略?或者使用託管運行時實現這種應用程序是一個壞主意? –

+0

@itadapter謝謝。我不再爲那家公司工作,但那是我們最終做的 - 對非託管狀態進行編組 - 而且你是對的,它解決了問題。 –

回答

1

在你的實現中你可以做一些普通的事情來使它更友好:一個相對容易的就是減少對象圖中對象引用的數量。例如,替代:

class Graph { 
    List<Node> roots; 
    // ... 
} 

class Node { 
    Node[] outwardEdges; 
    // ... 
} 

間接引用,通過節點的標識符:

class Graph { 
    List<Node> roots; 
    Node[] allNodes; 
    // ... 
} 

class Node { 
    int[] outwardEdges; 
    // ... 
} 

或類似的東西適合你的設計。這減少了收集器必須行走的對象圖中的指針數量。

將數據轉移到本地堆上是另一種可能性,即編寫一個小的JNI庫,爲您提供執行所需操作的界面。這可以通過其他方式得到回報:上次我遇到類似問題需要解決時,我們通過這種方法節省了大量空間,因爲我們在數據集中主要使用了西方文本數據,因此佔用的空間少得多,編碼爲UTF8。只要圖搜索的成本不是微不足道的,那麼本地調用的開銷就不太可能成爲問題。