Providing users with thread type
Jean Christophe Beyler
jcbeyler at google.com
Sun Apr 21 01:00:37 UTC 2019
Ahh there lies the problem of understanding then :)
We can provide that for our users that can use a non-vanilla OpenJDK.
Vanilla OpenJDK cannot use that kind of thing since there is no "C" style
symbol you could dlsym to. I don't think there is a good mechanism to
currently piece the information together using a vanilla OpenJDK.
So this conversation is about providing a mechanism for all OpenJDK agent
writers to figure this out, even if they had to jump through hoops. The
pthread_getname_np would have been a good one presumably but it seems that
a lot of systems just rename the native threads for some reason...
Hence I was offering to either extend AsyncGetCallTrace method (or create a
side-one) or extend the JVMPI_CallTrace structure. Either of these would
allow profilers to gather this information on future vanilla OpenJDKs. If
that makes sense,
Jc
On Sat, Apr 20, 2019 at 6:14 PM David Holmes <david.holmes at oracle.com>
wrote:
> 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
>
--
Thanks,
Jc
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/serviceability-dev/attachments/20190420/e5a6ab61/attachment-0001.html>
More information about the serviceability-dev
mailing list