当前位置: 首页 > 面试题库 >

由于权属空间的压缩,.hashcode()将返回不同的int吗?

南门意蕴
2023-03-14
问题内容

如果我Object.hashcode()在某个对象上调用该方法,它将返回该对象的内部地址(默认实现)。该地址是逻辑地址还是物理地址?

在垃圾回收中,由于内存压缩,对象在内存中发生移位。如果我在GC之前和之后调用哈希码,它将返回相同的哈希码(返回),如果是,则为什么(由于压缩地址可能会更改)?


问题答案:

@erickson或多或少是正确的。返回的哈希码java.lang.Object.hashCode()在对象的生存期内不变。

(通常)实现此方法的方式非常聪明。当对象由垃圾回收器重定位时,其原始哈希码必须存储在某个地方,以防再次使用。实现此目的的明显方法是将32位字段添加到对象标头中以保存哈希码。但这会给每个对象增加1个字的开销,并且在最常见的情况下会浪费空间…在这种情况下,hashCode不会调用对象的方法。

解决方案是将两个标志位html" target="_blank">添加到对象的标志字中,并按如下方式(大致)使用它们。hashCode调用方法时设置第一个标志。第二个标志告诉该hashCode方法是使用对象的当前地址作为哈希码,还是使用存储的值。当GC运行并重定位对象时,它将测试这些标志。如果设置了第一个标志而未设置第二个标志,则GC在对象的末尾分配一个额外的单词,并将原始对象位置存储在该单词中。然后,它设置两个标志。从此以后,该hashCode方法从对象末尾的单词获取哈希码值。

实际上,identityHashCode实现 必须以这种方式
来满足常规hashCode合同的以下部分:

“只要在Java应用程序执行期间在同一对象上多次调用它,hashCode方法
就必须一致地返回相同的整数,只要没有修改该对象的equals比较中使用的信息即可 。一个应用程序的执行到同一应用程序的另一个执行。”

如果/当GC将对象移至其他地址时,假设的实现identityHashCode()仅返回对象的 当前
机器地址将违反突出显示的部分。解决此问题的唯一方法是(假想的)JVM确保一旦hashCode调用对象就永远不会移动它。这将导致堆碎片的严重而棘手的问题。



 类似资料:
  • 我们正在Java-8-Oracle上运行。 我们在六个月前转移到java8。 在过去的几天里,我们得到了一个OOME不时,我们没有能够识别或再现的问题。 当我们执行对服务器(tomcat)的调用时,我们会在StackTrace上得到以下错误: 重新启动服务器解决了问题。对其他服务器的相同调用可以工作,对同一服务器的另一种类型的调用也可以工作。 查看GC日志时,我们会看到: 返回: 我在jstat日

  • 问题内容: 为什么不: 代替: 获得唯一哈希码的更高机会? 问题答案: 因为数组的最大长度为。 由于的主要用途是确定将对象插入/ 的后备数组中的哪个插槽,因此hashcode> 将无法存储在该数组中。

  • 我有一个简单的基本AWS架构,我无法使它工作。 CIDR 3个子网: 192.168.0.0/26 192.168.80.0/26 192.168.160.0/26 CIDR: 3个子网: 192.170.0.0/26 192.170.80.0/26 192.170.160.0/26 SSH端口22源代码192.168.0.0/16,这样我就可以从VPC1中的实例ssh < li>SSH端口22源

  • 问题内容: 今天,我了解并决定将其使用和测试。我知道整数是不可变的,因此id应该是(?)相同。但是,当我在提示中进行测试时,我注意到了一些细微的差异,并想找出其背后的原因。 凉!到目前为止,所有签出。但是之后… 好的,所以测试一下,我注意到此行为一直持续到256年。id最多可以是8位数字,然后257将返回更大的id,可以是15位数字。因此类型必须是8个字节。 所以我发现它与8个字节长有关,但是任何

  • 问题内容: 我正在实现一个程序,将文件分解为git blob并适当地存储它。 我有一个基于git书的文章的ruby参考实现 我正在尝试在这里实施 但是,我遇到了一个问题,即每个实现中存储的压缩数据略有不同。 显示前2个字节是相同的(如从该测试脚本运行)(如果我没有看错)。这些字节分别存储压缩方法,标志和标志(根据https://tools.ietf.org/html/rfc1950)。第三个字节是

  • 问题内容: 我正在阅读Head First Java的书中的一句话: 关键是哈希码可以相同,而不必保证对象相等,因为该方法中使用的“哈希算法” 可能会为多个对象返回相同的值。 为什么该方法可能为不同的对象返回相同的值?这不会引起问题吗? 问题答案: *对对象进行 *散列 意味着“ 找到可以由相同实例一次又一次地再现的良好的描述性值(数字) ”。由于Java的哈希码类型为,因此只能具有不同的值。这就