ObjectSynchronizer iterate only in-use monitors?

David Holmes david.holmes at oracle.com
Wed May 17 02:53:08 UTC 2017


This seems to be diverging and expanding in scope somewhat.

Any changes to the monitor lifecycle requires very careful 
consideration. Moving monitors to the Java heap could have wide 
spreading implications and cause quite severe perturbations in heap 
usage patterns. You would need very extensive testing of numerous real 
world apps to ensure this change is actually safe and performant. To me 
we are now well into JEP territory, not just tweaking existing policies. 
Such experiments should be trialed in a sandbox repo before being 
proposed to the mainline.

Cheers,
David

On 17/05/2017 12:38 AM, Roman Kennke wrote:
> Hi Carsten,
>
> thanks for the detailed explanations!
>
> Regarding MonitorInUseLists, we have seen very considerable improvements
> in GC processing time when using MonitorInUseLists, I wouldn't really
> like the idea of having to decide between SP-free-deflation and
> MonitorInUseLists. However, I also see that it doesn't make much sense
> to have a deflater thread mess with thread-local monitor allocs. My
> current idea is basically what I was starting with: to make each
> JavaThread deflate its own monitors when arriving at or leaving from a
> safepoint. Doing it on SP arrival has the disadvantage that it
> potentially stalls everybody else, but has the advantage the the GC
> would benefit from fewer monitors. Doing it on SP leave is opposite:
> threads don't have to wait  for each other when deflating their stuff,
> but GC would potentially see more monitors than it strictly needs to. I
> need to give it some more thought.
>
> I also need to give your idea to place monitors on Java heap more
> thought :-) (You are a crazy man!)
>
> Cheers,
> Roman
>
> Am 16.05.2017 um 15:53 schrieb Carsten Varming:
>> Dear Roman,
>>
>> I didn't do anything to extend it to work with MonitorInUseLists (it
>> wasn't on by default at the time). If MonitorInUseLists is enabled,
>> then my patch is a noop. MonitorInUseLists makes every java thread do
>> more work when inflating locks. That work is thread local and trying
>> to get it to work in the presence of a deflater thread might not be
>> productive.
>>
>> Re races:
>>
>> 1. To avoid endless inflation / deflation cycles I only attempt to
>> deflate a monitor the second time I see it: If the service thread (the
>> only thread deflating monitors) see a monitor in state New, then mark
>> it as Old and move on. So there is little interaction between a thread
>> inflating a lock to a monitor and the deflating thread (the service
>> thread), the inflating thread just have to make sure the monitor is
>> marked New and this marker is published using appropriate barriers.
>> The code already does the right thing as the displaced mark word has
>> to be correctly published for the hashcode races to be resolved.
>>
>> 2. An interesting race is between a thread acquiring the monitor and
>> the service thread trying to deflate the monitor. The the monitor is
>> free (_owner == NULL), then the service thread installs -1 in _owner
>> to let everyone else know that it will attempt to deflate the monitor.
>> This causes other threads to use the slow path on this monitor, but
>> otherwise general threads do not make a difference between _owner ==
>>  -1 and _owner == NULL. The -1 marker is used to ensure that no other
>> thread has acquired the monitor while we read _count and _waiters. If
>> the deflater thread manage to install -1 in _owner, read _waiters ==
>> 0, and make _count very negative if _count == 0, and _owner is still
>> -1, then _waiters must still be 0 as other threads has to acquire the
>> monitor to increase _waiters, and _count is still negative (I
>> displaced _count by a very large amount). That the is the signal to
>> other threads deflation is in progress. The actual deflation
>> (installing the displaced mark word in java object) is an idempotent
>> operation and both deflater thread and general threads will attempt to
>> complete the deflation. If any of the conditions mentioned above are
>> not true, then the monitor is in use. In that case we restore _count
>> if needed. If the deflating thread managed to install -1 in _owner,
>> but fail to make _count negative, then the next thread writing to
>> _owner (acquiring the lock), erases the -1 installed by the deflater
>> thread.
>>
>> 3. Installing the displaced mark word in the java object might also
>> race with a thread writing the hashcode. This race was pretty simple
>> to sort out as it is very similar to two thread both trying to install
>> a hashcode.
>>
>> Finally, do we really want monitors on the C-heap? We could store
>> monitors in the java heap. It wouldn't be that hard to teach the GCs
>> to check if the mark word is a pointer into the java heap, and
>> potentially copy the monitor object and update the pointer in the mark
>> word. This would avoid treating monitors as roots in the first place.
>> When should monitors be deflated? In such a scheme I propose to
>> deflate monitors when a java thread releases the lock using a simpler
>> approach than outlined in my patch (since the thread owns the monitor
>> is just have to make _count very negative to signal that this monitor
>> is being deflated), the safepoint counter could be used to prevent
>> more than one deflation per safepoint. WDYT?
>>
>> Carsten
>>
>> On Tue, May 16, 2017 at 8:05 AM, Roman Kennke <rkennke at redhat.com
>> <mailto:rkennke at redhat.com>> wrote:
>>
>>     Am 16.05.2017 um 13:37 schrieb Carsten Varming:
>>>     FYI. Last year I wrote a small patch[1] against JDK9 that enables
>>>     monitor deflation to happen outside a safepoint. There was little
>>>     interest then, so I never proposed it as a patch. The JDK9 code
>>>     has moved on a little bit, so the patch probably doesn't apply
>>>     cleanly, but the patch shows one way to complete the life of a
>>>     monitor without going through a safepoint.
>>
>>     Wow, now that is interesting!
>>
>>     Can you give me a quick summary-description how you avoid racing
>>     with other threads that might inflate the monitor? As far as I
>>     know, monitor deflation (currently) requires that all Java threads
>>     stand still at a safepoint.
>>
>>     Can it also be made to work with MonitorInUseLists?
>>
>>     Roman
>>
>>>
>>>     Carsten
>>>
>>>     [1] http://cr.openjdk.java.net/~cvarming/monitor_deflate_conc/0/
>>>     <http://cr.openjdk.java.net/%7Ecvarming/monitor_deflate_conc/0/>
>>>
>>>     On Tue, May 16, 2017 at 6:32 AM, Roman Kennke <rkennke at redhat.com
>>>     <mailto:rkennke at redhat.com>> wrote:
>>>
>>>         Am 16.05.2017 um 11:48 schrieb Robbin Ehn:
>>>         > Correction,
>>>         >
>>>         > On 05/16/2017 11:45 AM, Robbin Ehn wrote:
>>>         >> Yes, but since we are at a safepoint you should be able to
>>>         use gc
>>>         >> worker in that case also?
>>>         >
>>>         > or the java thread. And scratch 'also' :)
>>>
>>>         This clearly requires co-operation from the GC.
>>>
>>>         Also, I noticed that some GCs cannot do deflation during root
>>>         scanning,
>>>         because they stow away mark words during marking, and
>>>         temporarily store
>>>         forwarding pointers into the mark words, and only restore
>>>         mark words
>>>         after GC. This obviously conflicts with monitor deflation.
>>>         Which means
>>>         we need some GC cooperation there too... I will figure
>>>         something out.
>>>
>>>         Roman
>>>
>>>
>>
>>
>


More information about the hotspot-runtime-dev mailing list