比 JVMTI GetTag 更快的获取对象标签的方法
Faster alternative to get tags for objects than JVMTI GetTag
在使用异步分析器和 gperftools 进行分析时,我注意到 jvmti->GetTag
在我的代理结果中出现了很多。当我检查它是如何实现的时,我在 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));
}
- 虽然我的测试只有一个真正处于负载下的线程,但一旦我添加更多线程并大量使用
GetTag
,这似乎会更小。
我想使用标签为某些对象分配一个 id 并在我的 jvmti 代理中使用它。有什么更快的方法可以做到这一点吗?弄乱对象头显然不是一种选择(据我所知)。
注意:大多数事情应该在 C 端完成,因为我不希望我的 Java 代理以任何方式干扰应用程序。我所说的干扰甚至是指改变某些中心对象的内部状态/类(例如 java.lang.StringCoding
),或导致某些 类 被加载等
GetTag
已经在当前的 JVMTI 代理中大量使用,所以我正在寻找一种更快的方法来获取标签或实现我自己的机制,同时留在 C 端。
当您使用来自 C 的 Java 对象时,您基本上会受到 JNI 和 JVMTI 函数的限制。他们确实有不可避免的开销。
恐怕没有其他合法方法可以从本地代理访问 Java 对象。特别是,处理 naked oop 是非法的——这只是一个原始指针,它可能随时失效,因为对象可以移动。
然而,JVM 可以使用 oops,甚至可以使用对象地址作为 JvmtiTagMap
中的键,只要它在移动对象时更新相应的 oops。 HotSpot JVM 确实做到了这一点,参见 JvmtiTagMap::do_weak_oops.
在使用异步分析器和 gperftools 进行分析时,我注意到 jvmti->GetTag
在我的代理结果中出现了很多。当我检查它是如何实现的时,我在 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));
}
- 虽然我的测试只有一个真正处于负载下的线程,但一旦我添加更多线程并大量使用
GetTag
,这似乎会更小。
我想使用标签为某些对象分配一个 id 并在我的 jvmti 代理中使用它。有什么更快的方法可以做到这一点吗?弄乱对象头显然不是一种选择(据我所知)。
注意:大多数事情应该在 C 端完成,因为我不希望我的 Java 代理以任何方式干扰应用程序。我所说的干扰甚至是指改变某些中心对象的内部状态/类(例如 java.lang.StringCoding
),或导致某些 类 被加载等
GetTag
已经在当前的 JVMTI 代理中大量使用,所以我正在寻找一种更快的方法来获取标签或实现我自己的机制,同时留在 C 端。
当您使用来自 C 的 Java 对象时,您基本上会受到 JNI 和 JVMTI 函数的限制。他们确实有不可避免的开销。
恐怕没有其他合法方法可以从本地代理访问 Java 对象。特别是,处理 naked oop 是非法的——这只是一个原始指针,它可能随时失效,因为对象可以移动。
然而,JVM 可以使用 oops,甚至可以使用对象地址作为 JvmtiTagMap
中的键,只要它在移动对象时更新相应的 oops。 HotSpot JVM 确实做到了这一点,参见 JvmtiTagMap::do_weak_oops.