Java GC:为什么两个幸存者空间 [英] Java GC : Why Two Survivor Spaces

查看:106
本文介绍了Java GC:为什么两个幸存者空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在大多数在线教程中,我们可以看到他们显示GC中有两个幸存者空间。
当我们实际上只有一个生存空间时,需要什么?
有两个幸存者空间对性能有什么影响?解析方案

原因是,你猜对了,表现。首先让我解释为什么存在这些幸存空间。关于 object relocation 的基本问题,有两种主要垃圾收集器设计:


  • an in-place compacting 收藏夹;


  • a 收藏夹。




复制收集器可以更快速地运行,并且可以高效地并行化,这基本上是因为它不会覆盖任何对象。在每次GC运行后,如果不使用一个活动和一个休眠堆空间,这两个交换角色是无法实现的。

复制收集器的基本设计< h2>

注意:下面的内容并不是描述HotSpot的实际GC,而是它的那些方面,它们是原始设计的一部分,如CJ Cheney的1970年ACM论文。 HotSpot增加了进一步的改进,其中之一是添加下面解释的 Eden 空间。

当复制收集过程开始时,有两个涉及的空间:
$ b


  • 空间:连续的内存块分成两个区域:
    <

  • 新对象(自上次GC开始创建);
  • >
  • space:完全为空。



GC运行的任务是识别 空间中的所有存活对象并将它们复制到 空间。



em> 空间正在建立, 空间将被完全撤离,并且不需要写入任何内容。



复制GC是单遍



复制收集器的一个关键优点是它是单遍:我们只扫描所有GC根,复制所有这些对象,然后扫描这些对象对象以供进一步参考,复制所有参照物。我们从不重新访问任何对象,也不需要任何支持内存结构。 (查看
此处对此有一个很好的解释) / p>

转发指针



当每个存活对象被重新定位时,旧位置可以被标记为转发指针,然后可以有效地使用这些信息,因为扫描存活的对象以引用重定位的对象,并更新这些引用。旧的参考指向前向指针,所以新的指针值只是一个查找。



为什么第三个空格?



你的问题,为什么有两个幸存者空间? 为什么单独的 Eden 空间?。



HotSpot引入了 Eden 空间作为保持新分配区域的容量不变的优化,将大部分对象立即变为垃圾的结果押注在下面。您可以将 Eden 视为两个空格之间的内存 shared 的一部分—这部分可能会在下一个GC中释放。这实际上提高了内存利用率。


In most of the tutorials online, we can see that they show there are two survivor spaces in GC. What is the need to have two survivor spaces when we can actually have only one? What are the impacts on performance by having two survivor spaces?

解决方案

The reason is, you are guessing it right, performance. Let me first explain why the survivor spaces exist at all. There are two primary garbage collector designs with respect to the essential concern of object relocation:

  • an in-place compacting collector;

  • a copying collector.

The copying collector can operate faster and can be efficiently parallelized, basically because it never overwrites any objects. It cannot achieve that without using one "active" and one "dormant" heap space, these two switching roles after each GC run.

Basic design of a copying collector

Note: what follows is not a description of HotSpot's actual GC, but rather those aspects of it which are a part of the original design as presented in a 1970 ACM paper by C.J. Cheney. HotSpot adds further refinements, one of which is the addition of the Eden space explained below.

When a copying collection procedure starts, there are two spaces involved:

  • From space: a contiguous block of memory split into two regions:
    • survivors from the last GC;
    • new objects (created since last GC);
  • To space: completely empty.

The task of the GC run is to identify all surviving objects in the From space and copy them into the To space.

As the To space is being built up, the From space will be completely evacuated and nothing needs to be written to it.

Copying GC is single pass

A key advantage of the copying collector is that it is single-pass: we just scan all the GC roots, copying all those objects, and then scan those objects for further references, copying all the referents. We never revisit any object and don't need any support memory structures. (Look here for a good explanation of this).

Forward pointers

As each surviving object is relocated, the old location can be marked with a forwarding pointer and this information can then be efficiently used as the surviving objects are scanned for references to the relocated objects, and those references updated. The old reference points to the forward pointer so the new pointer value is just one lookup away.

Why the third space?

Your question, "why are there two survivor spaces?" would actually better be phrased, "why a separate Eden space?".

HotSpot has introduced the Eden space as an optimization which keeps the capacity of the new allocation region constant, betting on the outcome that a large proportion of the objects will immediately turn into garbage. You can look at Eden as a portion of memory shared between the two spaces—the portion that will probably get freed upon the next GC. This actually improves memory utilization.

这篇关于Java GC:为什么两个幸存者空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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