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

Java VM是否会在内存中移动对象?

巫马阳飙
2023-03-14
问题内容

Java虚拟机是否曾经在内存中移动对象,如果是,它将如何处理对移动对象的更新引用?

我问是因为我正在探索一种以分布式方式(即,跨多个服务器)存储对象的想法,但是出于效率方面的考虑,我需要能够在服务器之间移动对象。对象需要能够包含彼此的指针,甚至指向远程服务器上的对象。我正在尝试考虑更新对移动对象的引用的最佳方法。

到目前为止,我的两个想法是:

  1. 在对象的整个生命周期中都不会移动的地方保持引用间接,如果对象移动,我们将更新该引用。但是-如何管理这些间接?
  2. 保留每个对象的反向引用列表,因此我们知道如果移动对象必须更新哪些内容。当然,这会产生性能开销。

我会对这些方法的反馈以及其他替代方法的建议感兴趣。


问题答案:

参考上面关于遍历堆的注释。

不同的GC采取不同的方式。

通常,在遍历堆时复制收集器,但它们不会遍历堆中的所有对象。相反,它们将实况对象放在堆中。含义是,如果可以从“根”对象访问该对象,则该对象是活动的。

因此,在此阶段无论如何都要触摸所有活动对象,因为它会将它们从旧堆复制到新堆。一旦完成活动对象的复制,旧堆中剩下的全部就是已经复制的对象或垃圾。到那时,旧堆可以被完全丢弃。

这种收集器的两个主要好处是,它在复制阶段压缩了堆,并且仅复制了活动对象。这对于许多系统而言很重要,因为使用这种收集器,对象分配非常便宜,实际上只不过是增加堆指针而已。当发生GC时,不会复制任何“死”对象,因此它们不会降低收集器的速度。事实证明,在动态系统中,临时垃圾比长期存在的垃圾要多得多。

此外,通过遍历活动对象图,您可以看到GC如何“了解”每个对象,并跟踪它们,以便在复制期间执行任何地址调整用途。

这不是一个讨论GC机理的论坛,因为这不是一个小问题,但这是复制收集器工作原理的基础。

世代复制的GC将把“较旧”的对象放在不同的堆中,与“较新”的堆相比,最终收集这些对象的频率降低了。从理论上讲,持久耐用的物体会被提升到较老的世代,并且越来越少地被收集,从而提高了整体GC的性能。



 类似资料:
  • 问题内容: 我编写了一个简单的程序,在free()之后测试动态分配的内存的内容,如下所示。(我知道释放后我们不应该访问该内存。我编写此代码是为了检查释放后内存中将存在什么) 输出:3 0 我以为它将通过第二个打印语句打印垃圾值或崩溃。但是它总是打印0。 1)这种行为是否取决于编译器? 2)如果我尝试使用free()两次释放内存,则会生成核心转储。在手册页中,提到程序行为异常。但是我一直在获得核心转

  • 问题内容: 在ExpressJS for NodeJS中,我们可以执行以下操作: 提供所有静态CSS,JS和图像文件。我的问题是: 1)当我们这样做时,Express是否会在每次提供一种资源时自动在服务器内存中缓存文件,还是从硬盘上读取文件? 2)执行此操作时,Express是否默认使用ETag将资源保存在客户端的硬盘上或仅在客户端的内存上? 问题答案: 静态中间件不进行服务器端缓存。它使您可以执

  • 问题内容: 我有下一个JSON: 知道JSON对象中是否存在“ dog”值的最佳方法是什么? 谢谢。 解决方案1 解决方案2(JQuery) 解决方案3(使用some()方法) 问题答案: JSON变量引用具有一个称为“名称”的属性的对象数组。我不知道最好的方法,但这就是我的工作吗?

  • 上面是我正在处理的JSON对象。我想检查键是否存在。我尝试了下面的代码,但它不起作用。有办法实现吗?

  • 问题内容: 我阅读了JVM内存模型,并对以下内容感到困惑: JVM是否将.class实例存储在其内存中。如果是,则在哪个区域。 就像在加载类后,JVM生成了机器级代码,然后开始执行机器代码指令,然后仅在堆上创建对象,并填充了方法区域。 perm gen等区域存储字节码还是机器级代码? 烫发与方法面积 我真的很感谢您对此主题的任何帮助。 谢谢。 问题答案: 1)文件将在加载时存储在permgen存储

  • 问题内容: 假设类型 A的 对象存储在DB中。这是我使用hibernate从数据库加载特定数据库的方式: 如果id = 1的对象不存在,我将得到 ObjectNotFoundException 。但是,有没有一种方法可以检查此类对象是否存在而不必捕获异常?我想拥有的是: 找不到hibernate文档… 问题答案: 您可以使用: 如果对象在数据库中不存在,它将返回null。您可以在Hibernate