垃圾收集会改变Java中的对象地址吗?
我读到垃圾收集会在运行时导致内存碎片问题。为了解决这个问题,压缩由JVM完成,它获取所有活动对象并为它们分配连续内存。 这意味着对象地址必须随时更改?而且如果发生这种情况,垃圾收集会改变Java中的对象地址吗?,java,performance,memory-management,garbage-collection,jvm,Java,Performance,Memory Management,Garbage Collection,Jvm,我读到垃圾收集会在运行时导致内存碎片问题。为了解决这个问题,压缩由JVM完成,它获取所有活动对象并为它们分配连续内存。 这意味着对象地址必须随时更改?而且如果发生这种情况, 对这些对象的引用是否也重新指定 这不会导致严重的性能问题吗?Java是如何应对的 如果你在内存中移动一个对象,它的地址就会改变。因此,需要更新指向它的引用。当连续(内存中)对象序列中的对象被删除时,会发生内存碎片。这在内存空间中造成了一个洞,这通常是不好的,因为连续的内存块具有更快的访问时间和更高的匹配查切线的概率,等等。应
如果你在内存中移动一个对象,它的地址就会改变。因此,需要更新指向它的引用。当连续(内存中)对象序列中的对象被删除时,会发生内存碎片。这在内存空间中造成了一个洞,这通常是不好的,因为连续的内存块具有更快的访问时间和更高的匹配查切线的概率,等等。应该注意的是,使用间接表可以防止引用更新达到所使用的最大间接级别 垃圾收集的性能开销适中,不仅在Java中,在其他语言中也是如此,例如C#。Java如何应对这种情况,执行垃圾收集的策略以及如何最大限度地减少其对性能的影响取决于所使用的特定JVM,因为每个JVM都可以随心所欲地实现垃圾收集;唯一的要求是它符合JVM规范 但是,作为一名程序员,您应该遵循一些最佳实践,以充分利用垃圾收集并将其对应用程序的性能影响降至最低。见、和。你可能想检查一下,但它有点密集 我读到垃圾收集会在运行时导致内存碎片问题 这不是垃圾收集堆的唯一问题。当您有一个手动管理的堆,并且以与前面分配不同的顺序释放内存时,您可能也会得到一个碎片堆。能够拥有与自动存储的后进先出顺序(又称堆栈内存)不同的生命周期,是使用堆内存的主要动机之一 为了解决这个问题,压缩由JVM完成,它获取所有活动对象并为它们分配连续内存 不一定是所有对象。典型的实现策略将内存划分为逻辑区域,并且一次只将对象从一个特定区域移动到另一个区域,而不是所有现有对象。这些策略可能包括物体的年龄,如世代收集器将年轻一代的物体从伊甸园空间移动到幸存者空间,或剩余物体的分布,如“垃圾优先”收集器,其将如名称所示,首先排出垃圾率最高的碎片,这意味着获得可用连续内存块的最小工作量 这意味着对象地址必须随时更改 当然,是的 而且如果发生这种情况,
调整引用的成本并不比标记阶段遍历引用的成本高得多。事实上,非并发收集器甚至可以将这两个步骤结合起来,在第一次遇到对象时传输对象,然后调整随后遇到的引用,而不是标记对象。实际的复制是更昂贵的方面,但如上所述,通过不复制所有对象,而是使用基于典型应用程序行为的特定策略(如分代方法或“垃圾优先”策略)来减少所需的工作量。引用不必更新。可以有一个间接表。@user207421是的,为了完整起见添加了它。