8

I've been wondering recently how lock (or more specific: Monitor) works internally in .NET with regards to the objects that are locked. Specifically, I'm wondering what the overhead is, if there are 'global' (Process) locks used, if it's possible to create more of those global locks if that's the case (for groups of monitors) and what happens to the objects that are passed to lock (they don't seem to introduce an extra memory overhead).

To clarify what I'm not asking about: I'm not asking here about what a Monitor is (I made one myself at University some time ago). I'm also not asking how to use lock, Monitor, how they compile to a try/finally, etc; I'm pretty well aware of that (and there are other SO questions related to that). This is about the inner workings of Monitor.Enter and Monitor.Exit.

For example, consider this code executed by ten threads:

for (int i=0; i<1000; ++i) 
{
    lock (myArray[i])
    {
        // ...
    }
}
  • Is it bad to lock a thousand objects instead of one? What is impact in terms of performance / memory pressure?
  • The underlying monitor creates a wait queue. Is it possible to have more than one wait queue and how would I create that?
atlaste
  • 30,418
  • 3
  • 57
  • 87
  • Not sure I know what you ask. The objects used as "locks" are simply references to reference types. It doesn't matter what is inside the object. `Monitor.Enter` will see if the reference in question is on its collection of already held "locks". If it is, it will block the thread until the reference is free. If the lock is/becomes free, it will be taken (put into that collection of references), and kept there until `Monitor.Exit`. In your example, if `myArray` is of type `X[]` where `X` is a reference type (i.e. not a struct or enum type), it will be fine. Depending on what is inside the block. – Jeppe Stig Nielsen Jan 10 '14 at 09:17
  • 1
    See http://stackoverflow.com/a/1808722/517852 – Mike Zboray Jan 10 '14 at 09:23
  • 1
    Also http://joeduffyblog.com/2007/06/24/clr-monitors-and-sync-blocks/ and http://msdn.microsoft.com/en-us/magazine/cc188793.aspx – Mike Zboray Jan 10 '14 at 09:33
  • You should `lock` as much as you need it. If there is a scenario, where you need 1000 locks, go with it. Making single lock for different purposes could be as bad, as having many locks, when you need just one. `lock` implementation is really something you should not worry about. Why would you want to interfere with it? What could be a possible reason for creating your own low-level `lock`-ing mechanism? – Sinatr Jan 10 '14 at 10:20
  • @Sinatr well, in most scenario's it's not about 'need', but a matter of choice isn't it? And if you have to choose anyways, imho it's better to understand the underlying mechanism and pick the right choice. – atlaste Jan 12 '14 at 12:09

2 Answers2

6

Monitor.Enter is not a normal .NET method (can't be decompiled with ILSpy or similar). The method is implemented internally by the CLR, so strictly speaking, there is no one answer for .NET as different runtimes can have different implementations.

All objects in .NET have an object header containing a pointer to the type of the object, but also an SyncBlock index into a SyncTableEntry. Normally that index is zero/non used, but when you lock on the object it will contain an index into the SyncTableEntry which then contains the reference to the actual lock object.

So locking of thousands of objects will indeed create a lot of locks which is an overhead.

The information I found was in this MSDN article: http://msdn.microsoft.com/en-us/magazine/cc163791.aspx

Anders Abel
  • 67,989
  • 17
  • 150
  • 217
  • Right, that answers most of what I was looking for. The global lock that I mentioned is the spinlock around `SyncTableEntry` and the memory overhead is roughly 72 bytes. Performance overhead is depending on hashing - assuming a very low number of collisions, this is probably roughly 0. Question that remains: is it possible to create multiple synctable's -- although I suppose it make sense that that's impossible. – atlaste Jan 10 '14 at 09:32
2

Here's a good place to read about monitors, memory barriers etc.

EDIT

Screen shot from the page in case page become down in future: enter image description here

SOReader
  • 5,697
  • 5
  • 31
  • 53