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)
A Synced block is essentially a wrapper that lets you embed content from one Notion page into other pages. Once done, you'll be able to see and edit that content from anywhere you've pasted the Synced block. If you've ever used block embeds in Roam Research, you'll be familiar with this concept.
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.
To sync content across pages, simply copy one or multiple blocks from one page, paste in another, then select Paste and sync . Drag across blocks to select content to sync, then copy ( cmd/ctrl + C ). Navigate to another page and paste ( cmd/ctrl + V ). Select Paste and sync .
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With