Java虚拟机是否曾在内存中移动对象,如果是,它如何处理更新对移动对象的引用?
我问,因为我正在探索以分布式方式存储对象的想法(即跨越多个服务器),但出于效率原因,我需要能够在服务器之间移动对象.对象需要能够包含指向彼此的指针,甚至包含远程服务器上的对象.我正在尝试考虑更新对移动对象的引用的最佳方法.
到目前为止我的两个想法是:
在对象的生命周期内不会移动的某处保持引用间接,如果对象移动,我们会更新该间接.但是 - 这些间接是如何管理的?
保留每个对象的反向引用列表,以便我们知道在移动对象时必须更新的内容.当然,这会产生性能开销.
我对这些方法的反馈以及对替代方法的任何建议感兴趣.
参考上面关于走堆的评论.
不同的GC会采用不同的方式.
通常在收集器走到堆时复制收集器,它们不会遍历堆中的所有对象.而是他们在堆中走LIVE对象.这意味着如果它可以从"根"对象到达,那么该对象就是实时的.
因此,在此阶段必须触摸所有活动对象,因为它将它们从旧堆复制到新堆.完成活动对象的副本后,旧堆中剩余的所有内容都是已复制的对象或垃圾.此时,旧堆可以完全丢弃.
这种收集器的两个主要好处是它在复制阶段压缩堆,并且它只复制活动对象.这对许多系统来说很重要,因为使用这种收集器,对象分配很便宜,实际上只是增加堆指针.当GC发生时,没有任何"死"对象被复制,因此它们不会减慢收集器的速度.在动态系统中也发现,与长期存在的垃圾相比,存在更多的小型临时垃圾.
此外,通过遍历实时对象图,您可以看到GC如何"了解"每个对象,并跟踪它们以进行复制期间执行的任何地址调整.
这不是讨论GC机制的论坛,因为它是一个非常重要的问题,但这是复制收集器如何工作的基础知识.
分代复制GC会将"较旧"的对象放在不同的堆中,并且最终收集的内容不会比"更新"的堆更少.该理论认为,长期持久的物体会被提升到老一代并且收集的越来越少,从而提高了整体GC的性能.