当前位置: 首页 > 知识库问答 >
问题:

对象的地址在其生命周期内是固定的吗?

孟浩然
2023-03-14

对象的地址在其生命周期内是不变的还是可以改变的?我只是认为对象的地址永远不会改变。它依赖于JVM吗?我没有找到任何明确的规范。

共有2个答案

巫马玉堂
2023-03-14

不是一般的。许多JVM垃圾收集器会四处移动对象,并且该语言不能保证对象的位置。

有一些GC(普通标记

注意,每个对象仍然可以包含一个(大部分)唯一的ID(至少在我见过的JVM中),部分是为了支持< code>hashcode的基本实现。

施招
2023-03-14

java中对象的地址不是固定的;相反,它可能会改变(取决于条件)。

这是因为通常对象是在eden空间中分配的。然后它们移动到幸存者空间,然后如果它们在一些垃圾收集周期中幸存下来,也移动到老一代空间。所以它确实改变了。但是如果对象被分配在eden空间中,并且通过留在同一个空间中进行垃圾收集,那么地址将不会改变。类似地,如果对象太大而不能在eden空间中分配,那么JVM在老一代中分配该对象,并且如果它通过停留在它被分配的地方而被垃圾收集,那么地址也不会改变。

还有一件事你应该知道,即使一个对象停留在一代中,如果它通过停留在同一代中而被垃圾收集,地址可能会改变,因为它可能在垃圾收集时被垃圾收集器移动,例如从伊甸园空间到幸存者,从幸存者到幸存者,甚至在压缩的情况下进入旧一代。

从以上情况可以清楚地看出,地址的移动是依赖于JVM的。

希望有帮助。

编辑

回答以下问题:

如果我创建一个新对象并将其存储在一个映射中,那么它将基于hashCode(根据java使用对象的内存位置生成)存储在映射中。现在对象的地址改变了(导致不同的哈希代码),因此根据答案,代码永远无法从映射中获取对象??

哈希代码由 JVM 保存在对象标头中。所以它是恒定的。创建对象时,默认情况下会将其分配给 1,但当您首次使用该对象时,它会被计算并存储在标头中。它在对象的整个生命周期中永远不会改变。

 类似资料:
  • 每个响应对象只有当在 servlet 的 service 方法的范围内或在 filter 的 doFilter 方法范围内是有效的,除非该组件关联的请求对象已经开启异步处理。如果相关的请求已经启动异步处理,那么直到AsyncContext 的 complete 方法被调用,请求对象一直有效。为了避免响应对象创建的性能开销,容器通常回收响应对象。在相关的请求的startAsync 还没有调用时,开发

  • 每个请求对象只在一个 servlet 的 service 方法的作用域内,或过滤器的 doFilter 方法的作用域内有效,除非该组件启用了异步处理并且调用了请求对象的 startAsync 方法。在发生异步处理的情况下,请求对象一直有效,直到调用 AsyncContext 的 complete 方法。容器通常会重复利用请求对象,以避免创建请求对象而产生的性能开销。开发人员必须注意的是,不建议在上

  • 我需要从当前feature文件调用一个.feature文件,并将一个变量从被调用的.feature文件传递给调用方.feature文件。我使用了karate.set()和karate.get(),但变量似乎不是这样传递的。在调用的.feature文件中,我将变量设置为“*def token=karate.get('xenpauth')”。在调用的.feature文件中,我尝试获得类似“*defxe

  • 本文向大家介绍本地存储的生命周期是什么?相关面试题,主要包含被问及本地存储的生命周期是什么?时的应答技巧和注意事项,需要的朋友参考一下 : 和 都能控制数据的存储时间。 是一个绝对的过期时间, 是文档被访问之后的存活时间(是相对时间)。默认是 。 : 当会话被关闭后(浏览器、标签页被关闭),就会被清除。与 用法一样。 : 除非被主动清除,不然永久储存在浏览器中。 : 没有过期时间,除非主动清除。

  • 就如泛型类型能够被限定一样,生命周期(它们本身就是泛型)也可以使用限定。: 字符的意义在这里稍微有些不同,不过 + 是相同的。注意下面是怎么说明的: T: 'a:在 T 中的所有引用都必须比生命周期 'a 活得更长。 T: Trait + 'a:T 类型必须实现 Trait trait,并且在 T 中的所有引用都必须比 'a 活得更长。 下面例子展示了上述语法的实际应用: use std::fmt

  • 一旦一个类被装载、连接和初始化,它就随时可以被使用。程序可以访问它的静态字段,调用它的静态方法,或者创建它的实例。作为Java程序员有必要了解Java对象的生命周期。 类实例化 在Java程序中,类可以被明确或隐含地实例化。明确的实例化类有四种途径: 明确调用new。 调用Class或者java.lang.reflect.Constructor对象的newInstance方法。 调用任何现有对象的