我目前正在为Java 1.7构建本机JVMTI代理。问题是我需要索引有关特定Java对象实例的一些数据。所以我的问题是我可以使用jobject类型的值作为对象的实例ID来检索我的索引数据吗?
我已经查找了有关jobject类型语义的任何信息。它是Object的内存位置的指针吗?它是一个堆栈指针地址吗?它是JVM内部结构的地址吗?所以我无法弄清楚jobject的值是否是Java对象生命中唯一且不可变的。
感谢您的帮助。
修改
根据JNI发现的here规范,jobject似乎是Object实例的指针。
答案 0 :(得分:2)
当你说“jobject type's value”时,我猜你的意思是toString返回的值。如果你看一下java doc它说:
类Object的toString方法返回一个字符串,该字符串由对象为实例的类的名称,符号字符“@”和对象的哈希码的无符号十六进制表示组成。换句话说,此方法返回一个等于值的字符串:
getClass().getName() + '@' + Integer.toHexString(hashCode())
如果您查看Java文档中的hashCode方法,请说明:
每当在执行Java应用程序期间多次在同一对象上调用它时,hashCode方法必须始终返回相同的整数
以及
尽可能合理,Object类定义的hashCode方法确实为不同的对象返回不同的整数。 (这通常通过将对象的内部地址转换为整数来实现,但JavaTM编程语言不需要此实现技术。)
更新:回应Ryan的评论:System.identityHashCode即使重写了哈希码方法,也会获得原始哈希码。但是,就像评论一样,它并不是真正独特的。
所以我想你的问题的答案是肯定的,它是不可变的,它很可能是唯一的,但你应该阅读你的JVM的文档或源代码。
答案 1 :(得分:1)
至少在HotSpot中,jobject确实是一个指向对象位置的指针,也就是说,取消引用它会给你一个每个对象唯一的地址,这是你询问的“唯一且不可变的身份”的一半。 。问题是垃圾收集过程中地址可能会发生变化,因为HotSpot可以移动对象。
JVMTI GetTag和SetTag函数在内部使用从对象位置到标记的哈希表。每当移动对象时,HotSpot都会更新此哈希表,这些内容无法从JVMTI代理的位置轻松复制。正如您所说的那样,使用标记分配您自己的唯一标识值可能是唯一的方法。