我有一個Windows控制檯應用程序,應該在幾天或幾個月內不重新啓動的情況下運行。該應用程序從MSMQ中檢索「工作」並處理它。有30個線程同時處理工作塊。來自隊列的大對象堆和字符串對象
來自MSMQ的每個工作塊約爲200kb,其中大部分工作塊分配在一個String對象中。
我注意到,在處理了大約3-4,000個這樣的工作塊之後,應用程序的內存消耗非常高,消耗1 - 1.5 GB的內存。
我通過探查器運行應用程序,並注意到大部分這種內存(可能是一個演出等)沒有在大對象堆中使用,但結構是零散的。
我發現這些未使用(垃圾收集)字節中的90%是以前分配的字符串。然後我開始懷疑從MSMQ進入的字符串被分配,使用和解除分配,因此是碎片化的原因。
據我所知,像GC.Collect(2或GC.Max ...)這樣的東西不會幫助,因爲他們gc大對象堆但不壓縮它(這是這裏的問題)。所以我認爲我需要的是緩存這些字符串並以某種方式重新使用它們,但由於字符串是不可變的,我必須使用StringBuilders。
我的問題是:無論如何不改變底層結構(即使用MSMQ,因爲這是我不能改變的),並且仍然避免每次都初始化一個新的String以避免碎片化LOH?
感謝, 雅尼斯
UPDATE:關於這些 「作品」 塊目前如何檢索
目前,這些被存儲爲MSMQ WorkChunk對象。每個對象都包含一個名爲Contents的字符串和另一個名爲Headers的字符串。這些是實際的文本數據。如果需要,我可以將存儲結構更改爲其他的存儲結構,如果需要,可以將潛在的存儲機制更改爲MSMQ以外的其他存儲結構。
在工作節點側目前我們做
WorkChunk塊= _Queue.Receive();
所以在這個階段我們沒有什麼可以緩存的。如果我們以某種方式改變了結構,那麼我想我們可以取得一些進展。無論如何,我們必須解決這個問題,所以我們會盡一切努力避免拋出數月的工作。
更新:我繼續嘗試下面的一些建議,並注意到這個問題不能在我的本地機器上運行(運行Windows 7 x64和64位應用程序)。這使事情變得更加困難 - 如果有人知道爲什麼那麼它真的有助於在本地重新解決這個問題。
你是如何收到這些字符串的?一旦他們是字符串,你就卡住了。我來自一個流或字節[]你可能有一些選擇。 –
嗨亨克 - 看看更新以獲取有關這些工作塊的更多信息 – Yannis
但這是一個實際的問題?具有> = 8GB RAM的64位PC上的1.5GB應該可以繼續。 –