How heavy are Java Monitors?
Asked Answered
H

3

15

Say I have an array of thousands of objects, and a small number of threads that might access each of the objects. I want to protect the access to one of the objects methods. Easiest way would be to declare that method as synchronized. However, that might result in creating thousands of monitors, whichever way they are implemented. If this were Win32, I'd never create thousands of kernel objects such as Mutex, but CRITICAL_SECTIONs might be plausible. I'm wondering what's the case in Java. Given the chance of contention is low, would the use of monitors impose more than the sheer amount of memory they require? How common a practice is it to use such low granularity synchronization in Java?

(There are obviously workarounds such as using a much smaller array of synchronization objects, which will be accessed using some hash. I'm not looking for a practical solution, I'm looking for an insight).

Helios answered 1/11, 2010 at 11:44 Comment(1)
Java objects come with a light weight lock built in. This memory is used whether you lock the object or not. In short, Java is designed and optimised to support per object locking.Jodijodie
A
14

You have already paid (most of, and in low-contention) the penalty for having the Monitors around by using Java... no sense not using them. Particularly in the low-contention case, they are very cheap (see Items 2.1, 2.2, 2.3 here and Item #1 here), and the JVM can optimize them away entirely for a number of cases. If you only use the object's monitor transiently, the JVM will make it "big enough" (meaning it begins as bit-flipping, might expand for simple contention cases to a stack-allocated atomic flag, and under persistent contention have a objectmonitor allocated for it; all of these will be unrolled back to the low-overhead case as contention abates) and reclaim the space later. To the extent that locking on these objects is the "right thing" on the application side, I'd say go for it.

However, there's a design smell here. Locking on so many objects doesn't sound great. Furthermore, if you have any sequential locking conditions, you're not going to be able to reason about potential deadlocks. I suggest you augment your question with more detail about the application, and we can ask whether locking on a large pool of objects is the Right Thing.

This presentation by Dave Dice gives some useful insight into how Java6 synchronization works, and this blog entry is a treasure trove of sync-on-Java information. If you really, really care about how "big" a full-on objectmonitor structure is (will come into play in the contended case), the code is here. The HotSpot internals wiki page also has some good in-depth information.

Allness answered 1/11, 2010 at 12:6 Comment(7)
Using Java doesn't mean I've already paid for all possible performance hits up front... Anyway, this is definitively a design question. My C++ nose does sense a smell, but I'm not used the Java scents... I'm actually not worried about deadlocks, because the operations are short and simple. On such cases, it is tempting to just throw a "synchronized", and be on the safe side. Yet I'm worried how well will that scale (I know in Win32 it won't, because kernel objects are expensive).Helios
@eran: Understood. If we know more about the application, we can dig into it. But given what you've told us, I'd say don't worry unless you have a measurable performance issue. In the uncontended case, you have paid almost all of the penalty already; there's some tiny cost of flipping an already-allocated bit somewhere for monitorenter/exit. If you actually see some non-trivial contention, you might need to dig deeper.Allness
@eran: If this is a high-performance application for which you're willing to invest some serious low-level attention, and you want the deep theory, take a look at Herlihy's Art of Multiprocessor Programming, elsevier.com/wps/find/bookdescription.cws_home/714091/… caution: deep stuff. But Java code and analysis is available for all the content.Allness
Thanks for the answers, andersoj. This in going to get anywhere near production, just trying to use the occasion and get some better understanding of a fundamental Java feature.Helios
"I'm actually not worried about deadlocks, because the operations are short and simple." Beware! Those properties don't guarantee freedom from deadlock.Christensen
@Stephen C, @eran: Only if by "short and simple" you mean "terminal, and impossible to enter any other monitor inside this call", then you may get deadlock freedom. If there is any chance of the thread locking one of these objects escaping from your control, escaping the context of the locked object, or doing a monitorenter on another object for any reason, you still risk deadlock.Allness
@ansersoj - that's what I would have said :-)Christensen
C
6

Java mutexes are cheap enough that you can have hundreds of thousands of synchronized objects and not notice it.

In the uncontended case, a Java mutex consists of just 2 bits in the flags word. The JVM only associates a heavy-weight OS lock object with a Java mutex when the mutex is contended, and then releases the OS lock when the mutex has been exited by all threads.

An overview of how Java mutexes are implemented may be found in slides 9 to 23 of this presentation from Javaone 2006.


Note that the implementation and performance of mutexes is liable to depend on the vendor / release of Java that you are using, and the platform that you are running on.

  • In early Java releases, mutexes were significantly more expensive.
  • There may well have been advances since JavaOne 2006 paper ... eiether published or not.
Christensen answered 1/11, 2010 at 12:31 Comment(1)
+1 great resource I hadn't found. Wish they would make some attempt to aggregate this stuff in one place.Allness
T
0

I think Collections.synchronizedCollection let one thread access the collection. However the problem of creating monitors exists.

Tiffinytiffy answered 1/11, 2010 at 12:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.