代码之家  ›  专栏  ›  技术社区  ›  Mark Heath

什么是“同步块”和减少计数的提示

  •  16
  • Mark Heath  · 技术社区  · 15 年前

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

    接收器块计数的内置解释说明如下:

    此计数器显示当前使用的同步块数。同步块是为存储同步信息而分配的每个对象数据结构。同步块包含对托管对象的弱引用,需要由垃圾收集器进行扫描。同步块不仅限于存储同步信息,还可以存储COM互操作元数据。此计数器旨在指示大量使用同步原语时出现的性能问题。

    不过,当我们切换到其他应用程序时,同步块计数似乎会被重置。究竟是什么导致这些被创建,有没有减少这些数量的技巧?

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

    1 回复  |  直到 9 年前
        1
  •  23
  •   Mike J    15 年前

    每次使用锁定原语时,例如 lock Monitor.Enter 在.NET平台中,针对要锁定的对象实例初始化同步块结构。如定义中所述,这些块可以保存更多信息,如对象的哈希代码和COM互操作信息。

    由于这些块在可存储内容方面受到限制,因此同时访问这些块会导致争用,从而导致对象头的内容成为CLR管理的系统范围同步块表的索引。当对象需要这些同步块时,clr能够回收它们。

    在等待系统内核对象之前,锁定对象总是导致CPU旋转。每当分配的CPU自旋不满足允许监视器获取关键段锁的要求时,将创建一个系统自动重置事件句柄,并将对其的引用放入相关的同步块中。等待此事件句柄的其他线程将阻塞事件句柄,直到拥有的线程触发事件句柄的释放。

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