What is a "Sync Block" and tips for reducing the count

13,086

Everytime you use a locking primitive such as lock or Monitor.Enter in the .NET platform, a sync block structure is initialized against the object instance to be locked. As stated in the definition, these blocks can hold more information such as the object's hash code and COM interop information.

Since these blocks are limited in what can be stored, accessing the blocks simultaneously causes contention which in turn causes the object header's contents to become an index into a table of system-wide sync blocks managed by the CLR. The CLR is able to recycle these sync block as and when object need them.

Locking on an object always incurs CPU spinning before waiting on a system kernel object. Whenever the allocated CPU spin is not satisified for allowing a monitor to acquire the critical section lock, an system auto-reset event handle will be created and a reference to it will be put in the associated sync block. Other threads waiting on this event handle will then block on the event handle until the owning thread has triggered the event handle's release.

Therefore, if this counter constantly increases, it is a sign that too many threads are on contention for a lock on one or more objects and these locks might never be getting released.

Share:
13,086
Mark Heath
Author by

Mark Heath

I'm the creator of NAudio, an open source audio library for .NET. I'm interested in any ways to improve the quality of my code, and teaching others the things I learn along the way. I'm also the author of several Pluralsight courses.

Updated on June 03, 2022

Comments

  • Mark Heath
    Mark Heath almost 2 years

    We have a Windows Forms application that uses a (third party) ActiveX control, and are noticing in the .NET performance objects under ".NET CLR Memory" that the number of "Sync Blocks" in use is constantly increasing (along with increasing memory usage), even though our application is sitting there idle.

    The built-in explanation for the sink block count states:

    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.

    The sync block count does seem to get reset when we switch to a different application though. What exactly causes these to get created, and are there any tips for reducing the number of these?

    (BTW, it really is spelled "sink block" in the list of performance counters. I'm not sure if its a typo or a plumbing joke)

  • Razor
    Razor almost 7 years
    Might also be relevant to mention that calling GetHashCode() also initialises the sync block.
  • user2864740
    user2864740 over 6 years
    @VincePanuccio I believe that was a .NET 1.1 thing? (Ie. does the CLR do that today?)
  • user2864740
    user2864740 over 5 years