monitors explosion

Karen Kinnear karen.kinnear at oracle.com
Thu May 26 05:41:59 PDT 2011


Peter,

Thanks for the correction - yes the flag increase the number of  
safepoints, not
the number of GCs.

In terms of when you do inflation - the basic reasons are:
1) If you do a wait or notify
2) If a lock is contended
3) JNI monitors
4) If one thread is setting the hash code while another thread is  
updating a lock

In terms of deflation:
1) when a thread dies, the thread's local free list goes to the global  
free list
2) At a safepoint, we walk the lists of monitors, deflating those that  
are not in use,
and putting them back on the global free list
3) The MonitorBound flag causes a more frequent safepoint
- and yes, it is hard to know how best to tune it

thanks,
Karen



On May 26, 2011, at 7:05 AM, Peter Levart wrote:

> On 05/25/11, Y. Srinivas Ramakrishna wrote:
>> Hi Peter --
>>
>> Which version of the JDK elicits this behaviour? The monitor leakage
>> sounds vaguely like a problem that i encountered before and which
>> was fixed a while back, but this may well be a new problem,
>> and i can't dig up the CR for the problem that I recall in
>> this code, or where the fix went to. (Karen might recall
>> the details because she pushed the fix/workaround for that one.)
>>
>
> The production environment that we first experienced this on is:
>
> SunOS nobiex1 5.10 Generic_141444-09 sun4v sparc SUNW,Sun-Blade- 
> T6320 with 32GB RAM
>
> and JVM was 1.6.0_23 with the following arguments:
>
> -Xmx28672m
> -XX:MaxPermSize=640m
> -XX:+DisableExplicitGC
> -XX:+UseParallelGC
> -XX:ParallelGCThreads=32
> -XX:+UseParallelOldGC
> -XX:LargePageSizeInBytes=256m
> -XX:+UseLargePages
> -XX:+UseCompressedOops
> -XX:+MaxFDLimit
> -XX:ReservedCodeCacheSize=256m
>
> Recently we upgraded to:
>
> java version "1.6.0_25"
> Java(TM) SE Runtime Environment (build 1.6.0_25-b06)
> Java HotSpot(TM) 64-Bit Server VM (build 20.0-b11, mixed mode)
>
> with no observed difference in behavior.
>
> We also tried with the latest:
>
> java version "1.7.0-ea"
> Java(TM) SE Runtime Environment (build 1.7.0-ea-b142)
> Java HotSpot(TM) Server VM (build 21.0-b12, mixed mode)
>
> with no observed difference.
>
> But when I tried with  1.6.0_25-b06 on amd64/Linux and 1.6.0_25-b06  
> on amd64/Solaris 11, I did not experience the JVM slow-down. But  
> this amd64 HW platform was actually a virtual machine on a VMware  
> host and I think I did not have more than 2 virtual CPUs assigned so  
> this might be the reason (when I did those tests I hadn't yet  
> established the reason for JVM slow-down).
>
> The work-arround we were are using in production (until I learned  
> about the -XX:MonitorBound option) and was found by chance is  
> awkward: loading the Yourkit Java profiler agent into the JVM. This  
> somehow inhibits the monitors explosion (we boot-up with approx  
> 16000 exant semaphores with profiler agent loaded).
>
>> This is the CR that i was thinking of:-
>>
>> 6852873 Increase in delta between application stopped time and  
>> ParNew GC time over application lifetime
>>
>> I can't tell much on how or if the fix/workaround got
>> into specific releases, but i am guessing it must be in
>> the latest 6uXX public release out there (6u25?).
>>
>> Also relevant might be this CR:
>>
>> 6988353 refactor sync subsystem
>>
>> By the way, that was such a nice bug report you filed
>> (we just need the JVM version info from you that's all);
>> i wish all of our customers were like you. Thanks!
>
> It was a learning excercise where I got intimate with DTrace and  
> some JVM internals...
>
>>
>> -- ramki
>
>
> On 05/26/11, Karen Kinnear wrote:
>> Peter,includes
>>
>> Yes, I've been running your test case with some existing flags we  
>> have
>> to help with this kind of problem. Thank you for the test case - that
>> really
>> helps.
>>
>> There is a flag -XX:MonitorBound=<int> which can limit the number of
>> monitors that a thread can hang on to. For the test case I randomly
>> tried -XX:MonitorBound=80 and it reduced the final deflating idel
>> monitors
>> reported time from
>> 0.624620 secs to
>> 0.0007840 secs
>
> It helps for our application too. I don't have to resort to loading  
> the Yourkit agent into the JVM any more. I set the value to 16000  
> since this is the amount that gets allocated when there is no bound  
> specified and yourkit agent is loaded.
>
>>
>> The number can be tuned for your specific application. If you set it
>> lower, it reduces the number of monitors tied-up, and therefore
>> reduces the amount of time spent deflating idle monitors. The trade- 
>> off
>> is that it increases the frequency of GC in order to free the  
>> monitors.
>
> Does it? It can increase frequency of safepointing, but do induced  
> safepoints trigger GC?
>
>> So you have to tune the number to your specific application needs,
>> so as to minimize overall pause time. A recommended place to start  
>> would
>> be with # threads * # locks per thread at a steady state, where #  
>> locks
>> is actually number of allocated monitors, which reflects contended  
>> locks
>> and locks for which you use wait/notify.
>
> There are not many in our code, but I have a feeling that Oracle  
> Coherence might be using much more in some situations. For example,  
> it has a feature where you can "atomically" modify multiple entries  
> in a Map and we use that to isolate "transactions". This feature  
> works by placing "locks" on each modifying entry in some defined  
> order. All in all it's hard to determine the maximum amount of  
> monitors that could at some time be needed at once. I'll start with  
> a big limit that still doesn't make deflation pauses noticable...
>
>>
>> The flag is available in JDK7. I believe it was also backported to
>> JDK6u19.
>>
>> hope this helps,
>
> It does. Thank you.
>
>> Karen
>
> On 05/26/11, David Holmes wrote:
>> Is there some specific reason that taking the hashCode of a locked
>> object forces inflation here? We may need to look at why inflation is
>> happening and whether there is something the application and/or
>> libraries can do to mitigate it. (As well as considering what  
>> happens in
>> the VM of course).
>
> I used hashCode() just to prevent compiler to optimize the code  
> away. I didn't realize that invoking hashCode() could interfere with  
> allocation of object monitors though. Could it?
>
> What I tried to achieve with the code was to establish a situation  
> where one thread (Allocator) inflated/allocated the monitor and  
> another thread (Collector) freed it so that it was returned to it's  
> private list. But I don't know if that is what is going on. 1st I  
> don't know exactly when the monitor has to be inflated/allocated: at  
> the first uncontended entry into the synchronized block or at the  
> first contended synchronyzation. 2nd I don't know exactly when the  
> monitor is freed (returned to the private free list) and to which  
> thread's free list (the one that allocated it or the one that is  
> freeing it). Is there any documentation about what code is generated  
> by JIT? There are helpfull comments in synchronize.cpp but I haven't  
> yet been able to grasp the whole picture about monitors.
>
>>
>> David
>
>
> Regards, Peter



More information about the hotspot-runtime-dev mailing list