看到代表通过并行的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