作者Killercat (杀人猫™)
看板java
标题Re: [问题] HashCode 与 记忆体位置的关联
时间Mon May 25 16:37:15 2015
※ 引述《noapaov (单身汉)》之铭言:
: 最近看了一下书籍, 不太清楚理解是否有错, 想请教一下各位
: Object 类别所提供的 hashCode() method, 主要是返回物件的记忆体位置
: 经过运算後的整数, 所以与记忆体有密切关系
: 所以每个物件的HashCode()理论上应该都不一样, 但是有些子类别继承後会
: 进行equals和HashCode的覆写,例如String、Array等, 所以就有可能造成 :
: 如果两个物件使用equals(Object) 测试结果为不相等,
: 则这两个物件呼叫 hashCode 时,可以获得不同的整数结果("可以相同,也可以不同")
: 所以总结是如果继承Object类的子类别, 没有对equals hashCode进行改写,
: 那麽这些物件产生的HashCode应该都不一样, 但如果重写就有可能造成HashCode相等, 但不一定是参考相同的记忆体位置情况
: 不知道原理是否是这样
回文一下好了,我简单说一下
1. hashCode()不见得跟记忆体位置有关,有兴趣翻一下OpenJDK的String.hashCode()
他的实作方式保证你看了会笑出来
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/
classes/java/lang/String.java
缩 :
http://tinyurl.com/mqguft4
2. 追下去原始码的话你会发现 Object的hashCode是native
但是你只要对现代Java的GC有一点认识的话,就知道GC是会搬动记忆体的
从Java6引入Hotspot GC以降,整个heap被分为young/old/permgen
http://www.cubrid.org/blog/dev-platform/understanding-java-garbage-collection/
也就是说,你一个object的物件在记忆体里面的位置根本是会跑来跑去的
他的hash会因此变来变去吗?不会。那你觉得hashCode跟记忆体有没有关系呢?
目前来讲「应该」是没有,不然按这种搬法,要是有第二个object出现在heap同位置
那不就死翘翘了?
我提供一下OpenJDK hashCode()的native C code给你参考一下
不同JVM有不同实作,不过我想再有implement Hotspot的JVM下
我想应该仅仅只是一个序列号而已
http://tinyurl.com/mhhrehs (他实作请搜寻get_next_hash,可以对照.h去对签名)
在OpenJDK的VM实作,我们可以清楚地看到他其实只是一个递增序列
ok...这看不懂没关系
总之,虽然我没有Oracle JVM的原始码,但是我想....那本书应该是错的
这东西跟记忆体位置毫无关系
其实有兴趣可以去翻一下
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 59.124.251.135
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/java/M.1432543041.A.310.html
1F:→ Killercat: 附带一提,更复杂的说法是,hashCode()其实呼叫的源头 05/25 17:01
2F:→ Killercat: 是FastHashCode() 再呼叫get_next_hash() 05/25 17:01
3F:→ Killercat: 有兴趣的可以一路爬进去看看... 05/25 17:01
4F:→ Killercat: hash不会变请看line 617, 他是有cache的,做过一次就 05/25 17:02
5F:→ Killercat: 再也不会变动了,所以不管怎麽移位都是恒定的 05/25 17:02
6F:推 phstudy: Head First Java, 2nd是用Java 5... 05/25 17:49
7F:→ Chikei: 其实我觉得人家只是把javadoc上的说法搬过来....XD 05/25 17:51
8F:→ Chikei: doc上的Object.hashCode最後一段语意上的确是这样 05/25 17:52
9F:→ Chikei: 至於为何那样写...大有可能只是历史遗迹XD 05/25 17:54
10F:→ Killercat: java 5没Hotspot 所以可能是对的... 05/25 17:58
11F:→ Chikei: 有喔...java 5的GC是generational的 05/25 17:59
12F:→ Killercat: 那除非java5 hashCode会变,不然这本书可能是错的 05/25 18:00
13F:→ Killercat: java7原始码看起来hashCode一产生就是固定的了 05/25 18:00
14F:→ Chikei: hashCode产生後都是固定的阿,这在Object.hashCode有写 05/25 18:02
15F:→ Killercat: Java7是,不过我没把握Java5是不是啊... XD 05/25 18:03
16F:→ Killercat: 我在下面那篇有提,我有稍微翻spec,不过一时间找不到 05/25 18:03
17F:→ Killercat: 关於hash恒定性的条目。只是按常识来讲,hashCode要是 05/25 18:04
18F:→ Killercat: 会变来变去的话,应该是个很反直觉的事情 05/25 18:04
19F:→ Killercat: 不过spec等下班再仔细翻翻看 05/25 18:04
20F:→ Chikei: 会变来变去第一个就要问hash table怎麽办XD 05/25 18:06
21F:→ Killercat: 我想到的是thread会完蛋 XD 应该是不会变啦.... 05/25 18:09
22F:→ Killercat: 不过你的hash table比较直觉有说服力 XD 05/25 18:09