Java VM是否将对象移动到内存中?如果是这样 - 如何? [英] Does the Java VM move objects in memory, and if so - how?

查看:104
本文介绍了Java VM是否将对象移动到内存中?如果是这样 - 如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



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


  1. 维护一个引用间接引用,它不会在对象的生命周期中移动,如果对象移动,我们会更新它。但是 - 这些间接指针是如何管理的?

  2. 保留每个对象的反向引用列表,因此我们知道如果对象被移动必须更新什么。当然,这会导致性能开销。

我对这些方法的反馈感兴趣,并且对其他方法有任何建议。

解决方案

参考以上关于步行堆的注释。



不同的GC的做法不同。

通常在收集器走过堆时复制收集器,它们不会遍历堆中的所有对象。而是他们走在堆里的实物。其含义是,如果可以从根对象访问,则该对象是活的。



因此,在这个阶段必须触及所有的活动对象,因为它将它们从旧堆复制到新堆。活动对象的副本完成后,旧堆中的所有内容都是已经复制的对象或垃圾。在这一点上,旧堆可以完全丢弃。

这种收集器的两个主要优点是它在复制阶段压缩堆,并且只有它复制活物。这对于很多系统来说很重要,因为使用这种收集器时,对象分配是很便宜的,实际上它只是增加了一个堆指针。当GC发生时,没有任何死对象被复制,所以它们不会减慢收集器的速度。同样,在动态系统中,有很多很少的临时垃圾比垃圾长期存在。

另外,通过走动活动对象图,您可以看看GC如何能够知道每个对象,并跟踪它们是否出于在复制过程中执行的任何地址调整目的。



这不是讨论深度的论坛关于GC机制,因为它是一个不重要的问题,但这是复制收集器如何工作的基础知识。



分代复制GC会将旧对象置于不同的位置堆,最终收集的次数少于新堆。理论认为,持久的物体会被提升到老一代,并且越来越少地被收集起来,从而提高整体GC的性能。

Does the Java virtual machine ever move objects in memory, and if so, how does it handle updating references to the moved object?

I ask because I'm exploring an idea of storing objects in a distributed fashion (ie. across multiple servers), but I need the ability to move objects between servers for efficiency reasons. Objects need to be able to contain pointers to each-other, even to objects on remote servers. I'm trying to think of the best way to update references to moved objects.

My two ideas so far are:

  1. Maintain a reference indirection somewhere that doesn't move for the lifetime of the object, which we update if the object moves. But - how are these indirections managed?
  2. Keep a list of reverse-references with each object, so we know what has to be updated if the object is moved. Of course, this creates a performance overhead.

I'd be interested in feedback on these approaches, and any suggestions for alternative approaches.

解决方案

In reference to the comment above about walking the heap.

Different GC's do it different ways.

Typically copying collectors when they walk the heap, they don't walk all of the objects in the heap. Rather they walk the LIVE objects in the heap. The implication is that if it's reachable from the "root" object, the object is live.

So, at this stage is has to touch all of the live objects anyway, as it copies them from the old heap to the new heap. Once the copy of the live objects is done, all that remains in the old heap are either objects already copied, or garbage. At that point the old heap can be discarded completely.

The two primary benefits of this kind of collector are that it compacts the heap during the copy phase, and that it only copies living objects. This is important to many systems because with this kind of collector, object allocation is dirt cheap, literally little more than incrementing a heap pointer. When GC happens, none of the "dead" objects are copied, so they don't slow the collector down. It also turns out in dynamic systems that there's a lot more little, temporary garbage, than there is long standing garbage.

Also, by walking the live object graph, you can see how the GC can "know" about every object, and keep track of them for any address adjustment purposes performed during the copy.

This is not the forum to talk deeply about GC mechanics, as it's a non-trivial problem, but that's the basics of how a copying collector works.

A generational copying GC will put "older" objects in different heaps, and those end up being collected less often than "newer" heaps. The theory is that the long lasting objects get promoted to older generations and get collected less and less, improving overall GC performance.

这篇关于Java VM是否将对象移动到内存中?如果是这样 - 如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆