Providing users with thread type

David Holmes david.holmes at oracle.com
Sat Apr 20 23:14:16 UTC 2019


Hi Jc,

On 21/04/2019 8:15 am, Jean Christophe Beyler wrote:
> Hi David,
> 
> Hopefully this gives more details :)
> 
> Basically, in the Java agent, we set up a SIGPROF handler and we get a 
> handler call at a set frequency rate (generally the profiling is for 30 
> seconds). The thread that is doing the signal handler can be a thread 
> from the JVM and as we have said in this thread, internal VM threads 
> can't get a JNIEnv or are visible to JVMTI anyway so we can't really get 
> the name.

And yet ...

> Our current implementation, when faced with a thread like that, calls a 
> method like above that we added in the JVM to provide information about 
> what type of work was being done so that when we provide our profiles, 
> we can give that information to the user.

... they can call this method you added to the JVM? How do they do that? 
And if they can do that why can't they get the name the same way? Or 
call any existing query methods to piece together the information?

Cheers,
David

> However for agents that cannot use the modified JVM, we cannot provide 
> this information it seems and basically we have to fallback to getting 
> the PC and just attributing it to libjvm.so (see an example here 
> https://github.com/GoogleCloudPlatform/cloud-profiler-java/blob/master/src/profiler.cc#L127)
> 
> So basically, in cases where we are in a signal handler, where we are 
> asynchronous and cannot do a lot, getting a side method to just say : 
> "hey is this a compiler thread, is this a GC thread, etc." would 
> actually be helpful information during profiling instead of the general 
> "well this many threads were in libjvm.so but we don't know what was 
> going on".
> 
> I've thought about using some other information such as 
> CompilationMXBean to try to assess what is going on during profiling but 
> it seems hard to correctly attribute that back into the actual profiles 
> and untangle the libjvm.so buccket.
> 
> Hopefully this makes sense,
> Jc
> 
> On Sat, Apr 20, 2019 at 12:20 AM David Holmes <david.holmes at oracle.com 
> <mailto:david.holmes at oracle.com>> wrote:
> 
>     On 20/04/2019 10:29 am, Jean Christophe Beyler wrote:
>      > Hi David,
>      >
>      > On Fri, Apr 19, 2019 at 6:49 PM David Holmes
>     <david.holmes at oracle.com <mailto:david.holmes at oracle.com>
>      > <mailto:david.holmes at oracle.com
>     <mailto:david.holmes at oracle.com>>> wrote:
>      >
>      >     Hi Jc,
>      >
>      >     On 20/04/2019 12:30 am, Jean Christophe Beyler wrote:
>      >      > Problem is that if I don't have a jthread, I can't get the
>     name it
>      >      > seems. Perhaps it could help if I gave more information:
>      >      >
>      >      > - In our JVM profiling mechanism, we have a SIGPROF (and maybe
>      >     that's a
>      >      > wrong approach :-)) that gets cycled across threads (some Java
>      >     threads,
>      >      > some are the other threads)
>      >      >     - It is the other threads that I'm interested here to
>     be able to
>      >      > distinguish what they are in terms of of profiles
>      >      >
>      >      > Is there any way we could provide  that (not in JVMTI then)?
>      >      >     - The only way I could imagine perhaps doing this would be
>      >     perhaps
>      >      > to have a set of other tools at the same time running
>     (either using
>      >      > beans before/after or JFR) but this seems crude as well
>     (better than
>      >      > nothing though)
>      >      >     - I wish there was a way to just be able to get a type
>     for those
>      >      > internal frames while doing the actual SIGPROF handling
>      >      >
>      >      > FWIW, the method we expose basically is like this:
>      >      >      Thread* current_thread =
>      >     ThreadLocalStorage::get_thread_async_safe();
>      >
>      >     We have Thread::current_or_null_safe() for that.
>      >
>      >
>      > A decade old code might have rotted a bit (or been wrong from the
>      > start), I'll change this internal code :)
>      >
>      >
>      >      >      if (current_thread == NULL) {
>      >      >        return -1;
>      >      >      } else if (current_thread->is_Compiler_thread()) {
>      >      >        return _activity_compile;
>      >      >      } else if (current_thread->is_Java_thread()) {
>      >      >        return -1;
>      >      >      } else if (current_thread->is_GC_task_thread()) {
>      >      >        return _activity_gc;
>      >      >      } else if (current_thread->is_VM_thread()) {
>      >      >        VMThread* vm_thread = (VMThread*) current_thread;
>      >      >        VM_Operation* vm_op = vm_thread->vm_operation();
>      >      >        if (vm_op != NULL) {
>      >      >          switch (vm_op->type()) {
>      >      >            case VM_Operation::VMOp_GC_HeapInspection:
>      >      >            case VM_Operation::VMOp_GenCollectFull:
>      >      >            case VM_Operation::VMOp_GenCollectFullConcurrent:
>      >      >            case VM_Operation::VMOp_GenCollectForAllocation:
>      >      >            case VM_Operation::VMOp_ParallelGCFailedAllocation:
>      >      >            case VM_Operation::VMOp_ParallelGCSystemGC:
>      >      >            case VM_Operation::VMOp_CGC_Operation:
>      >      >            case VM_Operation::VMOp_CMS_Initial_Mark:
>      >      >            case VM_Operation::VMOp_CMS_Final_Remark:
>      >      >            case VM_Operation::VMOp_G1CollectFull:
>      >      >            case VM_Operation::VMOp_G1CollectForAllocation:
>      >      >            case VM_Operation::VMOp_G1IncCollectionPause:
>      >      >              return _activity_gc;
>      >      >            default:
>      >      >              break;
>      >      >          }
>      >      >        }
>      >      >      }
>      >      >      return _activity_other_vm;
>      >      > }
>      >
>      >     So it's not really the thread "type" but the logical
>     "activity". For
>      >     "type" you'd just need a query version of
>     Thread::print_on_error (more
>      >     or less).
>      >
>      >
>      >     Not at all sure where you could put this - nor clear why you
>     need to
>      >     put
>      >     it somewhere: isn't this just something executed by your SIGPROF
>      >     handler?
>      >
>      >
>      > Well problem is that I'm not in the JVM at the sigprof handler
>     level.
>      > I'm actually in the agent,
> 
>     Not sure what you mean. I'm assuming you're sending a SIGPROF to each
>     thread and using the handler for profiling - no? Otherwise please
>     clarify what is happening in each thread.
> 
>      > so basically from the agent's point of  view,
>      > I don't really know what "Activity" I just stopped but would love to
>      > know. We added internally this change to figure it out but I'd
>     like to
>      > get it in the open-source so that all could use it and not just us
> 
>     A "char* Thread::get_thread_type()" API might be useful (as I said a
>     query version of print_on_error(). But otherwise this seems something
>     peculiar to your agent so simply composing existing API calls - as you
>     outline - seems the appropriate way to deal with this.
> 
>     Seems to me the VMThread is the problem here because you want to try
>     and
>     attribute the VM_operation to different "buckets". But given the
>     bulk of
>     the work is actually done by other threads (e.g. GC), and going forward
>     less and less will be done by the VMThread itself (e.g. async monitor
>     deflation), is it really worth trying to classify this at a finer level
>     than just "in the VM"?
> 
>     Cheers,
>     David
> 
>      > internally. Basically, like I said ,when using open-source
>     profilers,
>      > this would help divide up the "libjvm.so" bucket that a lot of
>     profilers
>      > are getting.
>      > Thanks for your insight as always,
>      > Jc
>      >
>      >
>      >
>      >     David
>      >
>      >      > It's crude but we believe it is effective to at least
>     "bucketize"
>      >     the
>      >      > internals while doing our profiling.
>      >      >
>      >      > Thanks for your input,
>      >      > Jc
>      >      >
>      >      > On Fri, Apr 19, 2019 at 9:01 AM Alan Bateman
>      >     <Alan.Bateman at oracle.com <mailto:Alan.Bateman at oracle.com>
>     <mailto:Alan.Bateman at oracle.com <mailto:Alan.Bateman at oracle.com>>
>      >      > <mailto:Alan.Bateman at oracle.com
>     <mailto:Alan.Bateman at oracle.com>
>      >     <mailto:Alan.Bateman at oracle.com
>     <mailto:Alan.Bateman at oracle.com>>>> wrote:
>      >      >
>      >      >     On 19/04/2019 00:12, David Holmes wrote:
>      >      >      >
>      >      >      > I think it would be difficult to put something like
>     this
>      >     in JVM TI
>      >      >      > given that the use of threads within the JVM are
>     purely an
>      >      >      > implementation detail and not standardized in any
>     way. And
>      >     many of
>      >      >      > those threads are hidden from JVM TI anyway.
>      >      >      >
>      >      >      > The names of threads are the normal way to see what
>     "type"
>      >     of thread
>      >      >      > you're dealing with.
>      >      >     Right, JVM TI only deals with "Java threads" (jthread
>     object) and
>      >      >     has no
>      >      >     knowledge about other threads. It might be possible to
>     use its
>      >      >     extension
>      >      >     mechanism to provide information about other threads
>     but it
>      >     wouldn't be
>      >      >     interoperable with anything that use jtherad objects.
>      >      >
>      >      >     -Alan
>      >      >
>      >      >
>      >      >
>      >      > --
>      >      >
>      >      > Thanks,
>      >      > Jc
>      >
>      >
>      >
>      > --
>      >
>      > Thanks,
>      > Jc
> 
> 
> 
> -- 
> 
> Thanks,
> Jc


More information about the serviceability-dev mailing list