问题
When profiling with async profiler and gperftools I noticed that jvmti->GetTag
shows up quite a lot in the results for my agent. When I checked how it is implemented I found the following in the source of jvmitTagMap.cpp
:
jlong JvmtiTagMap::get_tag(jobject object) {
MutexLocker ml(lock());
// resolve the object
oop o = JNIHandles::resolve_non_null(object);
// for Classes get the tag from the klassOop
return tag_for(this, klassOop_if_java_lang_Class(o));
}
- Although my test only had one thread that was really under load it seems that this will scale even less once I add more threads and make heavy use of
GetTag
.
I wanted to use the tag to assign an id to certain objects and use it in my jvmti agent. Any ideas for a faster way accomplish that? Messing with the object header obvioulsy is not an option (to my knowledge).
NOTE: Most things should be done on C side as I do not want my Java agent to interfer with the application in any way. By interfer I even mean things like changing internal state of some central objects / classes (like java.lang.StringCoding
for example), or leading to some classes being loaded, etc
GetTag
is already used heavily throughout the current JVMTI agent, so I am looking for a faster way to get the tag or implement my own mechanism while staying on C side.
回答1:
When you work with Java objects from C, you are basically limited by JNI and JVMTI functions. And they do have inevitable overhead.
I'm afraid there are no other legal ways to access Java objects from a native agent. In particular, dealing with naked oop is illegal - this is just a raw pointer which may become invalid at any time because the objects can move.
JVM, however, can work with oops and even use the object address as a key in JvmtiTagMap
as long as it updates the corresponding oops whenever the objects are moved. And HotSpot JVM indeed does this, see JvmtiTagMap::do_weak_oops.
来源:https://stackoverflow.com/questions/53310123/faster-alternative-to-get-tags-for-objects-than-jvmti-gettag