1

This link mentions the number of monitors currently in a running JVM (i.e. 250000) https://bugs.openjdk.org/browse/JDK-8153224

How were they able to obtain that number?

Specifically, I want to obtain the number of idle monitors in a running system. We have observed a long "Stopping threads" phase i a gc run. The safepoint log shows that the time is spent in the "sync" phase. We are looking for culprits.

  • I would assume they tried by creating artificially that many and checking the result as they say in the bug report you've linked? – LinFelix Dec 13 '22 at 15:12
  • Does this answer your question? [What's a monitor in Java?](https://stackoverflow.com/questions/3362303/whats-a-monitor-in-java) – matt Dec 13 '22 at 15:24
  • Pretty much fire up a profiler and count the Objects – matt Dec 13 '22 at 15:25
  • @LinFelix I don't know how to check the result? My question is how to get it? – Morten Knudsen Dec 14 '22 at 11:16
  • @matt If it really is as simple as 1:1 object and monitor, I can't see the relevance of the legacy MonitorBound flag https://bugs.openjdk.org/browse/JDK-8230938, I mean it is possible to deflate the number? – Morten Knudsen Dec 14 '22 at 11:16
  • I guess the devils in the details. They are referring to active and idle monitors. I think in your question it isn't clear even though you literally say "idle monitors", in the body of your question you reference "monitors currently in a running jvm". Pretty much Objects have a monitor, Maybe you could improve your question. It sounds like you want to monitor the monitor. Which visualvm seems to do. – matt Dec 14 '22 at 11:54
  • @matt I have rephrased my question and added some details. Where does visualvm show the number of (idle) monitors? – Morten Knudsen Dec 16 '22 at 08:59

1 Answers1

2

It is true that every Java object can be used as a monitor, but the "idle monitors" that https://bugs.openjdk.org/browse/JDK-8153224 refers to are not simply objects. That wouldn't make sense. It would mean that the mere existence of lots of objects in the heap would delay GC "sync".

So what does it mean?


First we need to understand a bit about how Java monitors (primitive locks) work.

The default state of a monitor is "thin". In this state, the monitor is represented by a couple of lock bits in the object header. When a thread attempts to acquire a monitor that is in the thin state, it uses (I believe) a CAS instruction (or similar) to atomically test that the lock is thin+unlocked and flip it to thin+locked. If that succeeds, the thread has acquired the monitor lock and it proceeds on its way.

However, if the lock bits say that the monitor is already locked, the CAS will fail: we have lock contention. The locking code now needs to add the current thread to a queue for the monitor, and "park" it. But the object header bits cannot represent the queue and so on. So the code creates a "fat" lock data structure to hold the extra state needed. This is called lock inflation. (The precise details don't matter for the purpose of this explanation.)

The problem is that "fat" locks use more memory than "thin" locks, and have more complicated and expensive lock acquire and release operations. So we want to turn them back into "thin" locks; i.e. "deflate" them. But we don't want to do this immediately that the lock is released because there is a fair chance that the lock contention will recur and the lock will need to be reinflated.

So there is a mechanism that scans for "fat" locks that are current not locked and don't have threads waiting to acquire them. These are the "idle monitors" that the JDK-8153224 is talking about. If I understand what the bug report is saying, when the number of these "idle monitors" is large, the deflater mechanism can significantly delay the GC "sync" step.


This brings us to your problem. How can you tell if the deflater is what is causing your "syncs" to take a long time?

I don't think you can ... directly.

However, for this phenomenon to occur, you would need a scenario where there is a lot of thread contention on a large number of monitors. My advice would be to examine / analyze your application to see if that is plausible. (Note that the Twitter example involved thousands of threads and hundreds of thousands of monitors. It sounds a bit extreme to me ...)

There are other things (culprits) that can cause delays in the GC "sync" step. These include:

  • certain kinds of long running loops,
  • long running System.arraycopy() calls, and
  • having a large number of threads in RUNNING state.

So before spend lots of time on the "idle monitor" theory, I think you should do some safepoint profiling as mentioned in How to reduce time taken on threads reaching Safepoint - Sync state. Look for application threads that maybe the cause.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216