views:

272

answers:

1

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 "Sink 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 sink 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)

+2  A: 

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.

Mike J