Java虚拟机是否移动内存中的对象,如果是,如何移动?
Java虚拟机是否移动过内存中的对象?如果是,它如何处理对移动对象的更新引用 我这样问是因为我正在探索以分布式方式(即跨多个服务器)存储对象的想法,但出于效率原因,我需要能够在服务器之间移动对象。对象需要能够包含指向彼此的指针,甚至指向远程服务器上的对象。我在想更新对移动对象的引用的最佳方法 到目前为止,我的两个想法是:Java虚拟机是否移动内存中的对象,如果是,如何移动?,java,memory-management,garbage-collection,jvm,Java,Memory Management,Garbage Collection,Jvm,Java虚拟机是否移动过内存中的对象?如果是,它如何处理对移动对象的更新引用 我这样问是因为我正在探索以分布式方式(即跨多个服务器)存储对象的想法,但出于效率原因,我需要能够在服务器之间移动对象。对象需要能够包含指向彼此的指针,甚至指向远程服务器上的对象。我在想更新对移动对象的引用的最佳方法 到目前为止,我的两个想法是: 在对象生命周期内不移动的地方维护一个间接引用,如果对象移动,我们会更新该引用。但是,这些间接行为是如何管理的 为每个对象保留一个反向引用列表,这样我们就知道如果对象被移动,需要
- VM停止所有线程运行托管代码
- 它从一组已知的“根”执行可达性分析:静态变量、所有线程上的局部变量。对于找到的每个对象,它都遵循对象内的所有引用
- 任何未通过可达性分析识别的对象都是垃圾
- 然后,可以在内存中向下移动仍处于活动状态的对象,以便将它们密集地打包。这意味着对这些对象的任何引用也必须用新地址更新。通过控制垃圾回收的发生时间,VM能够保证没有会导致问题的对象引用“在空中”(即保存在机器寄存器中)
- 进程完成后,VM将再次启动线程执行
还有其他一些改进来支持并发垃圾回收,以及在调度GC时实际执行非托管代码的线程的详细信息,这给这一领域增加了更多的复杂性。您想要的关键字是“压缩垃圾回收器”。JVM被允许使用一个,这意味着可以重新定位对象。请参阅JVM手册,了解您的JVM是否有,并查看是否有任何命令行选项会影响它 从概念上讲,解释压缩的最简单方法是假设垃圾收集器冻结所有线程,重新定位对象,在堆和堆栈中搜索对该对象的所有引用,并用新地址更新它们。实际上,它比这更复杂,因为出于性能原因,您不希望在线程停止的情况下执行完全扫描,所以增量垃圾收集器将尽可能地为压缩做准备
如果您对间接引用感兴趣,可以从研究Java中的弱引用和软引用,以及各种RPC系统使用的远程引用开始。参考上面关于遍历堆的评论 不同的GC使用不同的方法 通常,当收集器遍历堆时,它们不会遍历堆中的所有对象。而是在堆中行走活动对象。这意味着,如果可以从“根”对象访问该对象,则该对象是活动的 因此,在这个阶段,is必须接触所有活动对象,因为它将它们从旧堆复制到新堆。一旦活动对象的复制完成,旧堆中剩余的所有对象要么是已经复制的对象,要么是垃圾。此时,旧堆可以完全丢弃 这种收集器的两个主要优点是,它在复制阶段压缩堆,并且只复制活动对象。这对许多系统都很重要,因为使用这种收集器,对象分配非常便宜,实际上只不过是增加一个堆指针。当GC ha