【问题标题】:How to uniquely distinguish Java's object instance如何唯一区分Java的对象实例
【发布时间】:2012-03-27 02:36:30
【问题描述】:

我目前正在为 Java 1.7 构建本机 JVMTI 代理。问题是我需要索引一些关于特定 Java 对象实例的数据。所以我的问题是我可以使用 jobject 类型的值作为对象的实例 ID 来检索我的索引数据吗?

我已经寻找有关什么是作业类型的语义的任何信息。它是对象内存位置的指针吗?它是堆栈指针地址吗?它是 JVM 内部结构的地址吗?所以我无法确定 jobject 的值在 Java 对象的生命周期中是否是唯一且不可变的。

感谢您的帮助。

编辑

根据发现here 的JNI 规范,jobject 似乎是Object 实例的指针。

【问题讨论】:

  • 到目前为止您做了什么?您尝试获取和索引或检索的信息的确切类型是什么?
  • 事实上,我的问题是关于用 C 编写的 JVMTI 代理。我想使用 Object 的实例作为主键进行缓存(例如实现为哈希映射或红黑树)现在,借助 SetTag 和 GetTag 函数,我用唯一的 id 标记每个对象。

标签: java jvmti


【解决方案1】:

当您说“jobject 类型的值”时,我猜您的意思是 toString 返回的值。如果您查看 java doc 它指出:

Object 类的 toString 方法返回一个字符串,该字符串由对象作为其实例的类的名称、at 符号字符“@”和对象哈希码的无符号十六进制表示形式组成。换句话说,这个方法返回一个字符串等于:

    getClass().getName() + '@' + Integer.toHexString(hashCode())

如果您查看 hashCode 方法的 Java 文档,它会指出:

在 Java 应用程序的执行过程中,只要在同一个对象上多次调用它,hashCode 方法必须始终返回相同的整数

还有

在合理可行的情况下,由 Object 类定义的 hashCode 方法确实为不同的对象返回不同的整数。 (这通常通过将对象的内部地址转换为整数来实现,但 JavaTM 编程语言不需要这种实现技术。)

更新:对 Ryan 评论的回复:System.identityHashCode 将获得原始哈希码,即使 hashcode 方法被覆盖。然而,就像 cmets 指出的那样,它并不是真正独一无二的。

所以我猜你的问题的答案是肯定的,它是不可变的,而且很可能是独一无二的,但你应该阅读你的 JVM 的文档或源代码。

【讨论】:

  • HashCode 对于每个对象都是唯一的。但是,如果您覆盖 equals,它应该被覆盖,这样它将与任何其他通过 equals 等效的对象相同。
  • @Ryan 不,它肯定总是独一无二的。很明显:您将很难在 64 位系统上使用 32 位来保证唯一标识符..
  • 另外,equals/hashcode 合约规定 2 个相等的对象具有相同的哈希码。因此,如果两个对象在语义上是相等的,那么它们的哈希码应该是相同的。但是,两个不相等的对象可能具有相同的哈希码,因此 System.identityHashCode(或任何哈希码实现)不能保证唯一性。
  • 我不认为“对象”类型的对象在语义上是相等的。他们的派生类可以,但 System.identityHashCode 会解决这个问题。仍然 Voo 关于 64 位地址的评论是唯一性将被破坏的真正原因。
  • 是的,我知道 Haschode 和 identityHashCode,但正如之前的 cmets 强调的那样,返回的值不能保证是唯一的
【解决方案2】:

至少在 HotSpot 中,jobject 确实是一个指向对象位置的指针,也就是说,取消引用它会为您提供每个对象唯一的地址,这是您询问的“唯一且不可变的标识”的一半.问题是地址在垃圾回收期间会发生变化,因为 HotSpot 可以移动对象。

JVMTI GetTag 和 SetTag 函数在内部使用从对象位置到标记的哈希表。每当对象移动时,HotSpot 都会更新此哈希表,这是您无法从 JVMTI 代理的位置轻松复制的内容。正如您所说,您已经在使用标签分配您自己的唯一身份值,这可能是唯一的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-31
    • 1970-01-01
    • 2018-01-12
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    • 2020-04-18
    • 2012-03-16
    相关资源
    最近更新 更多