c# - 什么是 "Sync Block"以及减少计数的技巧

标签 c# performance activex memory-management

我们有一个使用(第三方)ActiveX 控件的 Windows 窗体应用程序,并且在“.NET CLR 内存”下的 .NET 性能对象中注意到正在使用的“同步块(synchronized block)”的数量不断增加(随着随着内存使用量的增加),即使我们的应用程序闲置在那里。

接收器 block 计数状态的内置解释:

This counter displays the current number of sync blocks in use. Sync blocks are per-object data structures allocated for storing synchronization information. Sync blocks hold weak references to managed objects and need to be scanned by the Garbage Collector. Sync blocks are not limited to storing synchronization information and can also store COM interop metadata. This counter was designed to indicate performance problems with heavy use of synchronization primitives.

当我们切换到不同的应用程序时,同步块(synchronized block)计数似乎会重置。究竟是什么导致了这些创建,是否有减少这些数量的提示?

(顺便说一句,它确实在性能计数器列表中拼写为“sink block”。我不确定这是打字错误还是管道笑话)

最佳答案

每次您在 .NET 平台中使用诸如 lockMonitor.Enter 之类的锁定原语时,都会针对要锁定的对象实例初始化一个同步块(synchronized block)结构。如定义中所述,这些 block 可以保存更多信息,例如对象的哈希码和 COM 互操作信息。

由于这些 block 在可以存储的内容上是有限的,同时访问这些 block 会导致争用,这反过来会导致对象 header 的内容成为 CLR 管理的系统范围同步块(synchronized block)表的索引。 CLR 能够在对象需要时回收这些同步块(synchronized block)。

在等待系统内核对象之前,锁定对象总是会导致 CPU 旋转。每当分配的 CPU 自旋不满足以允许监视器获取临界区锁时,系统自动重置事件句柄将被创建,并且对它的引用将被放入关联的同步块(synchronized block)中。等待此事件句柄的其他线程随后将阻塞事件句柄,直到拥有线程触发事件句柄的释放。

因此,如果此计数器不断增加,则表明有太多线程争用一个或多个对象的锁,并且这些锁可能永远不会被释放。

关于c# - 什么是 "Sync Block"以及减少计数的技巧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1803298/

相关文章:

c# - 我应该对每个返回任务的方法使用异步/等待吗

java - 是否应该实例化实用程序类?

delphi - ActiveX 控件在 Delphi 应用程序中托管时无法正确处理箭头键

c++ - 为什么我在以受限用户身份运行时会在 DLLMain 中获得 GPF?

c# - 如何通过 C# 将数据包转发到另一个端口上运行的另一个 TCPClient

c# - 无法在 C# 中解析 Oracle 时间戳

database - 性能:软删除与移动条目

c# - 添加对 VS2008 项目的 VB6 ActiveX DLL 引用

c# - 创建一个json格式的对象

java - 返回两个数组列表或使用两种不同的方法