Thread.getState() very slow

Mandy Chung mandy.chung at oracle.com
Fri Jul 16 03:43:05 UTC 2010


Hi Doug, David,

I'm not aware of any CRs related to the performance of 
Thread.getState().  Like Alan said, the implementation hasn't been 
changed since JDK 5 release.  Probably the existing usage of 
Thread.getState() is not as performance sensitive as the starvation 
detector requires and thus the performance issue hasn't been noticed.

David Holmes wrote:
> Hi Doug,
>
> Doug Lea said the following on 07/11/10 21:20:
>> Also, while I'm at it, field Thread.threadStatus is suspiciously not
>> declared volatile.
>
> Agreed - technically this should be a volatile field. In practice I 
> think it only means that the window in which a stale value might be 
> seen is slightly longer. If threadStatus were exported directly it 
> might be more of an issue, but as an internal detail of getState() it 
> is not likely to be.
>
>>> Can you use Unsafe to grab the field directly, or would the 
>>> reflection make it too slow?
>>>
>>
>> That's what I'm currently doing as a sleazy workaround.
>> The sleaziness is not the Unsafe, which is basically fine
>> since this is planned for JDK code, but having to guess at startup
>> that the first value I get must be the one associated with RUNNABLE.
>
> I thought this would be fairly simple but looking deeper into this it 
> is a lot more complicated than I thought. There is a three-level 
> mapping from:
>
> OS/VM thread state -> VM ThreadStatus -> java.lang.ThreadState
>
> and it is a M:N:1 mapping
>

This is complicated than it needed to.

I vaguely remember that the current implementation considered the 
compatibility issue between different version of hotspot VM and JDK 
(e.g. older VM running on a newer JDK with a new Thread.State enum).   
Also, the java_lang_Thread::ThreadStatus in hotspot was defined as 
ordinal values that we wanted to avoid those values hardcoded in both 
hotspot and jdk.   Later it was changed to a hierarchical thread state 
represented as a bit vector (4980307) that we should have revised the 
implementation to map the bit vector directly to Thread.State enum but 
clearly the change in jdk was not done.

> At least a startup you should be able to get the current thread's 
> threadStatus and know that it represents RUNNABLE.
>
> In addition I suspect the lazy initialization may be more necessary 
> than I thought given the time at which this initialization might occur 
> during the VM initialization sequence. I'd have to experiment (once 
> I've remembered how to build regular SE Hotspot and the OpenJDK libs :) )
>
> Some input from the original implementors would be useful (Martin? 
> Mandy? ...)
>

Looking at the hotspot implementation 
(src/share/vm/classfile/javaClasses.hpp), java_lang_Thread::ThreadStatus 
is defined as a bit vector of JVMTI thread state flags:
   
http://download.java.net/jdk7/docs/platform/jvmti/jvmti.html#GetThreadState

I think making Thread.threadStatus a volatile field and using 
JVMTI_JAVA_LANG_THREAD_STATE_MASK to convert Thread.threadStatus to 
Thread.State enum would be a good solution.

> That all said, you are the best person to evaluate the performance 
> impact of any changes so it might be best if you are the one to do the 
> initial experiments - using a simple volatile + DCL for the init as a 
> first attempt perhaps.
>

It'd be great if Doug can do the experiment and evaluate the performance 
impact.  If you want me to prototype the jdk change, let me know and I 
should be able to make some time to do it next week.

Mandy

> David
>
>>
>> -Doug
>>




More information about the core-libs-dev mailing list