RFR: 8257967: JFR: Events for loaded agents [v17]
Serguei Spitsyn
sspitsyn at openjdk.org
Fri Apr 14 22:24:39 UTC 2023
On Fri, 14 Apr 2023 09:20:18 GMT, Markus Grönlund <mgronlun at openjdk.org> wrote:
>> src/hotspot/share/prims/jvmtiExport.cpp line 717:
>>
>>> 715: jvmtiEventVMInit callback = env->callbacks()->VMInit;
>>> 716: if (callback != nullptr) {
>>> 717: JvmtiAgent* const agent = lookup_uninitialized_agent(env, reinterpret_cast<void*>(callback));
>>
>> It was a surprise to me to discover this code in your changes.
>> How can it be possible that some agents are left uninitialized at the time of VMInit event?
>> Have you really observed this?
>> If so, then can you add a comment explaining the need of this initialization?
>> Is it needed for JFR purposes only?
>
> Ok. the terminology here might be confusing. The concept of an agent being "initialized" is introduced and reported by JFR. For example, here is the JFR event type definition for a NativeAgent:
> ```
> <Event name="NativeAgent" category="Java Virtual Machine, Diagnostics" label="Native Agent" description="A native programming language agent making use of the JVMTI interface used by development, profiling and monitoring tools"
> thread="false" startTime="false" period="endChunk" stackTrace="false">
> <Field type="string" name="name" label="Name" />
> <Field type="string" name="options" label="Options" />
> <Field type="boolean" name="dynamic" label="Dynamic" description="If the library attached to the JVM dynamically during runtime, i.e. not at startup" />
> <Field type="Ticks" name="initializationTime" label="Initialization Time" description="The time the JVM initialized the agent" />
> <Field type="Tickspan" name="initializationDuration" label="Initialization Duration" description="The duration of executing the JVMTI VMInit event callback. If no VMInit callback is specified, the duration is 0. For a dynamically loaded agent, it is the duration of executing the call to Agent_OnAttach." />
> <Field type="string" name="path" label="Path" description="The path of the library" />
> </Event>
>
> As you can see, there are two fields: initializationTime and IntializationDuration.
>
> We report these to let users understand when an agent was initialized (VMInit or Agent_OnAttach), together with the duration it took to execute either. For JavaAgents, it measures the invocation and duration of the premain or agentmain methods.
>
> "Initialized" does not mean "loaded" (at this point, all agents are loaded), but rather it means the agent has received a timestamp set as a function of VMInit. This timestamp and duration are what we will report in JFR as part of the event.
>
> An "uninitialized" agent is an agent who has not yet been timestamped, as part of VMInit, for example. Since an agent can create multiple JvmtiEnvs, the function is called lookup_uninitialized_agent() because we can only have a single timestamp for an agent, but it can, in turn, have multiple JvmtiEnvs. When looking up an agent again, using a second JvmtiEnv created by it, the agent is already "initialized", so no agent is returned.
>
> We cannot have the timestamping logic as part of the call out to Agent_OnLoad, because that call happens very early during VM bootstrap, so the Ticks support structures are not yet in place. But, timing the Agent_OnLoad call would be rather meaningless because the agent cannot do much except construct a JvmtiEnv and setting capabilities and callbacks.
>
> VMInit is where most of the invocation logic, at least for JavaAgents happens, so the measurements are placed there.
Thank you for explaining it.
Could you, please, add small comment explaining that it is for JFR purposes?
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/12923#discussion_r1167310779
More information about the serviceability-dev
mailing list