看到代表通過並行的foreach做了以下工作的併發性能分析:爲什麼我在這裏有鎖?
循環中的每個線程從DB和過程讀取裏面的數據。線程之間沒有鎖,因爲每個線程都處理不同的數據。
由於未知原因(請參見黑色垂直矩形),看起來像foreach的所有線程中存在週期性鎖定。如果您看到選定的鎖定段(深紅色),您將看到堆棧顯示鎖定在StockModel.Quotation構造函數中的線程。那裏的代碼只是構造了兩個空列表!
我讀的地方,這可能是由GC引起的,所以我已經改變了垃圾收集與服務器模式下運行:
<runtime>
<gcServer enabled="true"/>
</runtime>
我有一個小的改進(約10% - 15 %更快),但我仍然有各處的垂直鎖。
我也添加到所有數據庫查詢的WITH(NOLOCK),因爲我只讀數據沒有任何區別。
任何暗示這裏發生了什麼?
已完成分析的計算機有8個內核。
編輯:使微軟符號服務器後,結果證明,所有線程被阻塞像wait_gor_gc_done或WaitUntilGCComplete電話。我認爲啓用GCServer我有一個GC爲每個線程,所以我會避免「垂直」鎖,但似乎並非如此。我錯了嗎?第二個問題:由於機器沒有受到內存壓力(使用8個演出中的5個),有沒有辦法延遲GC執行或暫停它,直到並行foreach結束(或將其配置爲不太經常觸發)?
在你分配對象和鎖的很多情況下確實是由GC引起的,你有沒有嘗試剛剛起步的第三方物流工作之前強制GC.Collect的? GC.Collect與GCCollectionMode.Forced。 – Alex 2013-02-19 16:25:27
那麼,在循環內部,我將分配大量在每次迭代結束時「放棄」的小對象。如果它們是GC'ed,它可以鎖定整個線程集嗎? – 2013-02-19 16:33:55
啓用Microsoft Symbol Server以獲得更好的堆棧跟蹤。考慮到漫長的等待,這看起來像純垃圾收集。 – 2013-02-19 16:59:43