将Hashcode标识为Java对象

时间:2013-12-18 10:19:08

标签: java hashcode jvmti

我的一位朋友和我有下面的赌注:

可以使用Object使用Identity Hashcode在[{1}}中使用Object,从内存中再次获取System.identityHashCode()。受垃圾收集器尚未清除的限制。

我现在一直在寻找一个答案而且找不到明确答案。

我认为使用Java可能会这样做,但我还没有使用它。

你们中有人对此有答案吗?如果我可以在你的网站上这样做,你会买一个coffie;)

提前致谢, 菲利克斯

p.s:我说这种行为可以实现,我的朋友说这是不可能的

4 个答案:

答案 0 :(得分:7)

理论上,你可能会遇到一些问题。

  • 它是随机生成的,因此它不是唯一的。任意数量的对象(尽管不太可能)都可以具有相同的标识哈希码。
  • 它不是一个记忆位置,当从伊甸园,幸存者空间或终身空间移动时,它不会改变。
  • 您需要找到所有可能找到它的对象根。

如果您认为它对静态集合等已知对象可见,则应通过反射轻松导航。

BTW一旦64位OpenJDK / Oracle JVM,身份哈希码存储在偏移量为1的标题中,这意味着您可以读取它,甚至可以使用sun.misc.Unsafe更改它。 ;)

BTW2标头中存储的31位hashCode(非32位)是懒惰设置,也用于偏置锁定。即,一旦调用Object.hashCode()或System.identityHashCode(),就会禁用对象的偏向锁定。

答案 1 :(得分:1)

我认为你的朋友将赢得这个赌注。 Java / JVM为您管理内存,一旦您删除所有引用,就无法访​​问它。

幻影参考,弱参考等等都是为了让你正在描述的东西 - 所以如果你保持弱或幻影参考你可以。 identityHashCode既不是。

C和C ++可能会让你这样做,因为你有更直接的内存控制,但即使这样,你也需要内存位置而不是它的哈希值。

答案 2 :(得分:0)

不,因为identityHashCodes不一定是唯一的。它们不是指向对象的指针。

答案 3 :(得分:0)

没有。 identityHashCode不一定是内存地址:它只是hashCode的默认实现。它也不能保证对所有对象都是唯一的(但不同的实例应该有不同的identityHashCodes)。

即使identityHashCode是从内存地址派生的,也可以重新分配对象(但是根据定义,identityHashCode 不能更改)。