4

我的一个朋友和我有以下赌注:

可以通过使用收到的inObject来从内存中再次获取。具有尚未被垃圾收集器清理的限制。Identity HashcodeObjectSystem.identityHashCode()Java

我一直在寻找一个很长一段时间的答案,但无法找到一个明确的答案。

我认为使用 可能可以做到这一点JVMTI,但我还没有使用它。

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

在此先感谢,菲利克斯

ps:我是说这个行为可以实现,我的朋友说不可能

4

4 回答 4

7

理论上这是可能的,但是你有一些问题。

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

如果您可以假设它对静态集合等已知对象是可见的,那么它应该很容易通过反射进行导航。

顺便说一句,一旦是 64 位 OpenJDK/Oracle JVM,身份哈希码从偏移量 1 开始存储在标头中,这意味着您可以读取它,甚至可以使用 sun.misc.Unsafe 更改它。;)

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

于 2013-12-18T10:23:25.207 回答
1

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

幻影引用、弱引用等都旨在允许您所描述的内容 - 因此,如果您保留对某些东西的弱或幻影引用,您可以。identityHashCode 两者都不是。

C 和 C++ 可能允许您这样做,因为您可以更直接地控制内存,但即便如此,您也需要内存位置而不是它的哈希值。

于 2013-12-18T10:23:52.007 回答
0

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

于 2013-12-18T10:24:12.887 回答
0

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

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

于 2013-12-18T10:24:42.680 回答