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.hol...@oracle.com <mailto:david.hol...@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.hol...@oracle.com <mailto:david.hol...@oracle.com>
     > <mailto:david.hol...@oracle.com
    <mailto:david.hol...@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.bate...@oracle.com <mailto:alan.bate...@oracle.com>
    <mailto:alan.bate...@oracle.com <mailto:alan.bate...@oracle.com>>
     >      > <mailto:alan.bate...@oracle.com
    <mailto:alan.bate...@oracle.com>
     >     <mailto:alan.bate...@oracle.com
    <mailto:alan.bate...@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

Reply via email to