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

JVM GC是否可以在引用比较的中间移动对象,即使双方都引用同一个对象,也导致比较失败?

莫振
2023-03-14
问题内容

众所周知,GC有时会在内存中移动对象。据我了解,只要在移动对象时所有引用都被更新(在调用任何用户代码之前),这应该是绝对安全的。

但是,我看到有人提到引用比较可能是不安全的,因为对象在引用比较的中间被GC移动了,从而即使两个引用都应引用同一对象,该比较也可能失败?

也就是说,在任何情况下以下代码都不会显示“ true”吗?

Foo foo = new Foo();
Foo bar = foo;
if(foo == bar) {
    System.out.println("true");
}

我尝试使用谷歌搜索,但是缺乏可靠的结果使我相信说这是错误的人,但是我确实找到了各种各样的论坛帖子(例如这样的帖子),似乎表明他是正确的。但是,有人也说那不是事实。


问题答案:

Java字节码指令相对于GC始终是原子的(即,执行单个指令时不会发生周期)。

GC只能运行在两个字节码指令之间。

查看javac为代码中的if指令生成的字节码,我们可以简单地检查一下GC是否会产生作用:

// a GC here wouldn't change anything
ALOAD 1
// a GC cycle here would update all references accordingly, even the one on the stack
ALOAD 2
// same here. A GC cycle will update all references to the object on the stack
IF_ACMPNE L3
// this is the comparison of the two references. no cycle can happen while this comparison
// "is running" so there won't be any problems with this either

另外,即使GC能够在执行字节码指令期间运行,该对象的引用也不会更改。在循环之前和之后,它仍然是同一对象。

因此,简而言之,您的问题的答案是“否”,它将始终输出true。



 类似资料:
  • 我已经被覆盖了hashcode和equals以查找具有相同开始日期和关闭日期的值。我得到了重复对象的类似哈希代码。当等同于这些对象时,我得到了布尔值“假”。在我的理解中,对象==对象比较对象的引用,即使引用是相同的;代码返回假。你能帮我理解是什么问题吗?我在下面发布了我的代码: Main.java 输出: 检查客户对象引用:Customer@643 对象引用(位于Map中):[Customer@6

  • 两个 NavigableString 或 Tag 对象具有相同的HTML或XML结构时, Beautiful Soup就判断这两个对象相同. 这个例子中, 2个 <b> 标签在 BS 中是相同的, 尽管他们在文档树的不同位置, 但是具有相同的表象: “<b>pizza</b>” markup = "<p>I want <b>pizza</b> and more <b>pizza</b>!</p>"

  • 两个 NavigableString 或 Tag 对象具有相同的HTML或XML结构时, Beautiful Soup就判断这两个对象相同. 这个例子中, 2个 <b> 标签在 BS 中是相同的, 尽管他们在文档树的不同位置, 但是具有相同的表象: “<b>pizza</b>” markup = "<p>I want <b>pizza</b> and more <b>pizza</b>!</p>"

  • 问题内容: 我得到的错误就在这行 。 该怎么办?其他逻辑还可以吗? 我想做的是有一个A列表和一个B列表,其中一个属性与id相同;尽管变量名不同。即在和在B。现在我将两个列表都放在ListAll中,并在相同的变量id / bid上对它们进行排序。我有A和B实现可比性。 和我的listAll是对象类型? 我该怎么做?谢谢。 问题答案: 您可以添加一个通用基类并在那里进行比较,如下所示:

  • 我理解A,我们在那里有一个原语;没有引用。by-复制。 我希望B和C的行为与D相同——根据它们被给予的引用而改变。 为什么这个对象引用另一个对象只对用户定义的对象“起作用”,而不是整数、字符串等。?

  • 我有两个对象类Person和Employee。两个类都有共同的属性年龄。我已经在Arraylist中添加了这两个类的几个对象,现在我需要两个,写一个比较器,并将其传递给集合类的sort方法。并希望列表按年龄排序。我尝试这样做只是为了更清楚地使用Java中的carparable和Comparator。 编辑:我问这个问题的原因是我不清楚比较者和可比性。我在某个地方读到,如果类实现了可比较的,那么它就