[HotSpot 虚拟机垃圾收集调优指南-JavaSE11-笔记]-3-垃圾收集器实现

3-垃圾收集器实现

Java SE 平台的一大优势是它使开发人员免受内存分配垃圾收集的复杂性

但是,当垃圾收集是主要瓶颈时,了解实现的某些方面很有用。垃圾收集器对应用程序使用对象的方式做出假设,这些假设反映在可调参数中,这些参数可以在不牺牲抽象能力的情况下进行调整以提高性能。

3.1 分代垃圾收集

一个对象何时被认为是垃圾?,当正在运行的程序中任何其他活动对象任何引用 无法再访问它时,它的内存可以被 VM 重用。

理论上,最直接的垃圾收集算法在每次运行时都会迭代每个可达对象任何剩余的对象都被视为垃圾。这种方法所花费的时间活动对象的数量正比,这对于维护大量活动数据的大型应用程序来说是令人望而却步的。

Java HotSpot VM 结合了许多不同的垃圾收集算法,除了ZGC使用一种称为generational collection(分代收集). 虽然年轻代垃圾收集每次都会检查堆中的每个活动对象,但分代收集利用大多数应用程序的几个经验观察属性来最小化回收未使用(垃圾)对象所需的工作。这些观察到的特性中最重要的是weak generational hypothesis,它表明大多数物体只能存活很短的时间。

图 3-1中的蓝色区域是对象生命周期的典型分布。x 轴显示以分配的字节数衡量的对象生命周期y 轴上的字节数是具有相应生命周期的对象中的总字节数左侧的尖峰表示在分配后不久可以回收(换句话说,已经“死亡”)的对象。例如,iterator对象通常仅在单个循环的持续时间内处于活动状态。

在这里插入图片描述

图 3-1 对象生命周期的典型分布

有些对象的寿命更长,因此分布向右延伸。例如,通常在初始化时分配的一些对象会一直存在到 VM 退出。在这两个极端之是在一些中间计算期间存在的对象,这里被视为初始峰值右侧的块。一些应用程序具有非常不同的外观分布,但令人惊讶的大量应用程序具有这种一般形状。通过关注大多数对象“英年早逝”这一事实,可以实现高效的收集。

3.2 分代

为了针对这种情况进行优化,内存是分代管理的(内存池保存不同年龄的对象)。当代填满时,垃圾收集发生在每一代中。

绝大多数对象都分配在专用于年轻对象(年轻一代)的池中,并且大多数对象都死在那里。当年轻代填满时,会导致只收集年轻代的Minor GC;其他代的垃圾不回收。首先,此类收集的成本收集的活动对象的数量成正比;一个充满死亡对象的年轻代很快就会被收集起来。通常,在每次Minor GC期间,来自年轻代的部分幸存对象会移动到老年代最终老年代填满必须回收,导致Full GC,其中收集了整个堆。Full GC通常比Minor GC持续更长时间,因为涉及的对象数量要多得多。图 3-2显示了串行垃圾收集器中的默认分代排列:
在这里插入图片描述

图 3-2 Serial Collector 中的默认分代排列

启动时,Java HotSpot VM 将整个 Java 堆保存在地址空间中,但除非需要,否则不会为其分配任何物理内存。覆盖 Java 堆的整个地址空间在逻辑上分为年轻代年老代。为对象内存保留的完整地址空间可以分为年轻代和老年代。

年轻代由伊甸园Eden两个幸存者Survivor空间组成。大多数对象最初是在伊甸园Eden中分配的。一个幸存者Survivor空间任何时候都是空的,在垃圾回收时作为eden中活对象的目的地另一个survivor空间垃圾回收后,伊甸园和源幸存者空间为空。在接下来的垃圾回收中,交换了两个幸存者空间的用途。最近填充的一个空间是复制到另一个幸存者空间的活动对象的来源。对象以这种方式在幸存者空间之间复制,直到它们被复制了一定次数或那里没有足够的空间。这些对象被复制到年老代。这个过程也称为老化

3.3 性能注意事项

垃圾收集的主要衡量标准吞吐量延迟

  • 吞吐量是长时间考虑的未花费垃圾收集中总时间的百分比。吞吐量包括分配所花费的时间(但通常不需要调整分配速度)。

  • 延迟是应用程序的响应能力。垃圾收集暂停会影响应用程序的响应能力。

用户对垃圾回收有不同的要求。例如,有些人认为 Web 服务器的正确指标是吞吐量,因为垃圾收集期间的暂停可能是可以容忍的,或者只是被网络延迟所掩盖。但是,在交互式图形程序中,即使是短暂的停顿也可能会对用户体验产生负面影响。

一些用户对其他注意事项很敏感。占用空间是进程的工作集,以页面和缓存行为单位。在具有有限物理内存或许多进程的系统上,占用空间可能决定可伸缩性。即时性是对象死亡和内存可用之间的时间,这是分布式系统的一个重要考虑因素,包括远程方法调用 (RMI)。

一般来说,为特定一代选择大小是这些考虑因素之间的权衡。例如,一个非常大的年轻代可能会最大化吞吐量,但这样做是以牺牲占用空间、及时性和暂停时间为代价的。通过使用较小的年轻代,可以以牺牲吞吐量为代价来最小化年轻代的停顿。一代的大小不会影响另一代的收集频率和暂停时间。

没有一种正确的方法来选择一代的大小。最佳选择取决于应用程序使用内存的方式以及用户需求。因此,虚拟机对垃圾收集器的选择并不总是最佳的,可能会被命令行选项覆盖;请参阅后面一个博客《影响垃圾收集性能的因素》。

3.4 吞吐量和占用空间测量

吞吐量和占用空间最好使用特定于应用程序的指标来衡量。

例如,可以使用客户端负载生成器测试 Web 服务器的吞吐量。但是,通过检查虚拟机本身的诊断输出很容易估计由于垃圾收集而导致的暂停。命令行选项-verbose:gc 在每次收集时打印有关堆和垃圾收集的信息。这是一个例子:

[15,651s][info ][gc] GC(36) Pause Young (G1 Evacuation Pause) 239M->57M(307M) (15,646s, 15,651s) 5,048ms
[16,162s][info ][gc] GC(37) Pause Young (G1 Evacuation Pause) 238M->57M(307M) (16,146s, 16,162s) 16,565ms
[16,367s][info ][gc] GC(38) Pause Full (System.gc()) 69M->31M(104M) (16,202s, 16,367s) 164,581ms

上面日志中输出显示两个Young GC,然后是一个Full GC,该GC由应用程序通过调用System.gc(). 这些行以表明应用程序启动时间的时间戳开头。接下来是有关此行的日志级别 (info) 和标签 (gc) 的信息。后面是 GC 标识号。在这种情况下,有编号为 36、37 和 38 的三个 GC。然后记录 GC 的类型声明 GC 的原因。在此之后,会记录有关内存消耗的一些信息。该日志使用格式“在 GC 之前使用->“在 GC 之后使用”(“堆大小”)。

在示例的第一行中,这是 239M->57M(307M),这意味着在 GC 之前使用了 239 MB,并且 GC 清除了大部分内存,但 57 MB 幸存下来。堆大小为 307 MB。请注意,在此示例中,完整 GC 将堆从 307 MB 缩小到 104 MB。在内存使用信息之后,记录 GC 的开始和结束时间以及持续时间(结束 - 开始)。

该**-verbose:gc命令是 的别名-Xlog:gc加粗样式**。-Xlog是用于在 HotSpot JVM 中进行日志记录的常规日志记录配置选项。这是一个基于标签的系统,gc其中的标签之一。要获取有关 GC 正在做什么的更多信息,您可以配置日志记录以打印具有该 gc标记和任何其他标记的任何消息。命令行选项是 -Xlog:gc*.

下面是一个 G1 Young GC记录的示例-Xlog:gc*:

[10.178s][info][gc,start ] GC(36) Pause Young (G1 Evacuation Pause) 
[10.178s][info][gc,task ] GC(36) Using 28 workers of 28 for evacuation 
[10.191s][info][gc,phases ] GC(36) Pre Evacuate Collection Set: 0.0ms
[10.191s][info][gc,phases ] GC(36) Evacuate Collection Set: 6.9ms 
[10.191s][info][gc,phases ] GC(36) Post Evacuate Collection Set: 5.9ms 
[10.191s][info][gc,phases ] GC(36) Other: 0.2ms 
[10.191s][info][gc,heap ] GC(36) Eden regions: 286->0(276) 
[10.191s][info][gc,heap ] GC(36) Survivor regions: 15->26(38)
[10.191s][info][gc,heap ] GC(36) Old regions: 88->88 
[10.191s][info][gc,heap ] GC(36) Humongous regions: 3->1 
[10.191s][info][gc,metaspace ] GC(36) Metaspace: 8152K->8152K(1056768K)
[10.191s][info][gc ] GC(36) Pause Young (G1 Evacuation Pause) 391M->114M(508M) 13.075ms 
[10.191s][info][gc,cpu ] GC(36) User=0.20s Sys=0.00s Real=0.01s

技术咨询支持,可以扫描微信公众号进行回复咨询
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宋小生的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值