Reputation: 42441
This is a follow-up question to this one
So I keep exploring modern profilers capabilities from the "programmatic access" standpoint, and I came across something beyond my understanding.
This time I've stumbled upon The "Allocation Call Tree" feature in JProfiler:
I do see that in order to get this kind of information, I have to trigger the sampled allocation with a rate of 1/10 by default and then specify (preferably) the package in which the allocated classed will be recorded.
Step 1
Step 2
But then I don't really understand how can the information about the call-stacks be "matched" with the information about the allocated objects.
Of course my question is not about the implementation details of JProfiler, I understand its a commercial tool with a close code and everything, but rather about the general understanding of how can this kind of information can be retrieved.
My initial guess is that it somehow "instruments" the already-loaded class files to "intercept" each and every allocation for these objects (with a sampling rate to not slow down the process too much) but then what? Does it call something like Thread.currentThread().getStackTrace()
and records the actual stack trace that has led to the allocation?
On the other hand, its activated in the "sampling mode" (as opposed to the instrumentation) + there is a performance concern - this sounds a really expensive thing to do (read, should not be used in production) to me, but I might be wrong, so any advice will be appreciated.
Upvotes: 3
Views: 244
Reputation: 47975
My initial guess is that it somehow "instruments" the already-loaded class files to "intercept" each and every allocation for these objects
Since Java 11 delivered JEP 331 it uses these capabilities in the native JVMTI in order to sample allocations. Before Java 11, it instruments the java.lang.Object
constructor. As for the call stacks, it depends on whether instrumentation or sampling is used. For instrumentation, it uses the call stack that is already built by the instrumentation. For sampling, the call stack built by sampling is not precise enough, so it queries the call stack through JVMTI.
Does it call something like Thread.currentThread().getStackTrace()
For sampling it's a bit like that, but doing it in Java would create a huge overhead because of the many secondary allocations. JVMTI is a native interface and can do this more efficiently.
Upvotes: 3