Java 并行压缩收集器算法
我有两个问题。其中一人将谈论这个话题:) 1) 我面临的一个问题是,无法找到有关HotSpot中不同垃圾收集器如何工作的完整信息。但我不是在谈论垃圾收集器工作的一般描述(我们在互联网上有很多这样的信息),我是在谈论具体的算法。我找到了这份白皮书(Java热点虚拟机中的内存管理)。 但它只有一般的想法。它对并行压缩算法(我指的是并行标记扫描压缩)有很好的描述(可能不是很好,请看我的第二个问题),但它没有解释其他垃圾收集器的算法。然而,这份白皮书是我在互联网上能找到的最好的信息。我想知道的是,在哪里可以获得关于不同垃圾收集器(对于年轻一代,我的意思是:ParNew、DefNew、PSYoungGen;对于老一代:PSOLdGen、ParOldGen、Concurrent Mark Sweep)如何工作的完整描述/信息。无法相信用户无法获得此信息 2) 关于并行压缩收集器算法(ParOldGen或并行标记扫描压缩)的问题。白皮书(见第一个问题)对其工作进行了描述。让我粘贴白皮书中的一段引文(请花一分钟看一下): 下面列出了我无法理解的事情: 关于总结阶段:Java 并行压缩收集器算法,java,algorithm,garbage-collection,jvm-hotspot,Java,Algorithm,Garbage Collection,Jvm Hotspot,我有两个问题。其中一人将谈论这个话题:) 1) 我面临的一个问题是,无法找到有关HotSpot中不同垃圾收集器如何工作的完整信息。但我不是在谈论垃圾收集器工作的一般描述(我们在互联网上有很多这样的信息),我是在谈论具体的算法。我找到了这份白皮书(Java热点虚拟机中的内存管理)。 但它只有一般的想法。它对并行压缩算法(我指的是并行标记扫描压缩)有很好的描述(可能不是很好,请看我的第二个问题),但它没有解释其他垃圾收集器的算法。然而,这份白皮书是我在互联网上能找到的最好的信息。我想知道的是,在哪里
- 由于以前收藏的压缩,一些 每一代的左侧部分将是密集的,包含 大部分是活的物体。可以从中恢复的空间量 如此密集的区域不值得压缩它们
那么,这是否意味着当我们有一个由98-99%的活物体和2-1%的死物体组成的区域(换言之,死物体的一小部分)时,压缩这个区域就不值得从这样一个区域中恢复空间了。然而,这些微小的空闲空间(洞)最终会被填满,在垃圾收集完成后就不会有洞了
- 所以总结阶段要做的第一件事就是检查 区域,从最左边的区域开始,直到到达一个点 其中可以从某个区域恢复的空间以及可以从该区域恢复的空间 它的权利值得压缩这些地区的成本
- 该点左侧的区域称为密集区域 前缀,并且在这些区域中不移动任何对象
- 地区 该点右侧将被压实,消除所有死区
- 摘要阶段计算并存储第一个项目的新位置 每个压缩区域的实时数据字节
-
在压缩阶段,垃圾收集线程使用
用于确定需要填写的地区的摘要数据,以及 线程可以独立地将数据复制到区域中。这就产生了一个 一端密集堆积的堆,有一个大的空堆
在另一端堵住
请帮我弄清楚。这只是一个算法的一般描述。这些描述可以有不同的细节。在本例中,它提供了大部分细节,但仍为实现者留下了一些选择 关于你的问题:
所以“摘要阶段”没有压缩?上一阶段的目的是否只是查找所有可用空间?
-是的,这是正确的。摘要阶段收集索引数据并基本上确定所有必要的内容,以便压缩阶段可以执行复制。他们不知道如何实现压缩,但是默认的方法是将每个活动对象放在前一个对象的旁边。基本上,所有的空白空间都会被删除,压缩步骤完成后,您就有了一个连续的内存块,其中包含所有活动对象。我看到你们对第四部分感到困惑,但请注意它是用将来时态写的:“将被压缩”——所以不是在总结时,而是在以后这是否意味着[…]将该区域压缩到不值得从该区域恢复的空间?
是的,没错。实际上,您会损失一些空间,但用内存换取执行速度是很常见的。确切的密度阈值取决于实现,但我将使用的总内存比率阈值大致定在70-90%左右如果你想知道所有不干净的细节,请看一看开放源码VM实现,如评论中所建议的。如果你真的需要详细了解收集器的工作,你可以阅读代码。你在这里找不到很多详细页面的原因是,如果你开始担心你走错了路的细节,那么收集器的设计就是为你管理内存 最好的解决方案是使用内存分析器并降低分配率。不要对命令行选项进行太多的调整或干扰(除非