[HotSpot 虚拟机垃圾收集调优指南-JavaSE11-笔记]-8-ZGC垃圾收集器与其他注意事项

8-ZGC垃圾收集器与其他注意事项

8.1 Z垃圾收集器

Z 垃圾收集器 (ZGC) 是一种可扩展的低延迟垃圾收集器。ZGC 并发执行所有昂贵的工作,不会停止应用程序线程的执行超过 10 毫秒,这使得它适用于需要低延迟和/或使用非常大的堆(数 TB)的应用程序

Z 垃圾收集器作为实验性功能提供,并通过命令行选项启用 -XX:+UnlockExperimentalVMOptions -XX:+UseZGC。

8.1.1 设置堆大小

ZGC 最重要的调优选项是设置最大堆大小(-Xmx)。由于 ZGC 是并发收集器,因此必须选择最大堆大小,1) 以便 堆可以容纳应用程序的实时集,2) 堆中有足够的空间,允许在GC运行时为分配提供服务。需要多少净空空间在很大程度上取决于分配率和应用程序的活动集大小。一般来说,你给 ZGC 的内存越多越好。但与此同时,浪费内存是不可取的,所以这一切都是为了在内存使用和 GC 需要运行的频率之间找到一个平衡点。

8.1.2 设置并发 GC 线程数

第二个可能要查看的调优选项是设置并发 GC 线程的数量(-XX:ConcGCThreads)。ZGC 具有自动选择此数字的启发式方法。这种启发式通常效果很好,但根据应用程序的特性,这可能需要进行调整。这个选项本质上决定了应该给 GC 多少 CPU 时间。给它太多,GC 将从应用程序中窃取过多的 CPU 时间。给它太少,应用程序分配垃圾的速度可能比 GC 收集它的速度快。

8.2 其他注意事项

8.2.1 显式垃圾收集

应用程序可以与垃圾收集交互的另一种方式是使用System.gc().

这可能会在可能没有必要时强制执行主要收集major GC(例如,当次要收集Minor GC 就足够时),因此通常应该避免。显式垃圾收集的性能影响可以通过使用标志禁用它们来衡量-XX:+DisableExplicitGC,这会导致 VM 忽略对System.gc().

显式垃圾收集最常见的用途之一是远程方法调用 (RMI) 的分布式垃圾收集 (DGC)。使用 RMI 的应用程序引用其他虚拟机中的对象。如果不偶尔调用本地堆的垃圾收集,就无法在这些分布式应用程序中收集垃圾,因此 RMI 会定期强制进行完整收集。这些收集的频率可以通过属性来控制,如下例所示:

java -Dsun.rmi.dgc.client.gcInterval=3600000
-Dsun.rmi.dgc.server.gcInterval=3600000 …
此示例指定每小时一次的显式垃圾收集,而不是每分钟一次的默认速率。但是,这也可能导致某些对象需要更长的时间才能被回收。Long.MAX_VALUE如果不希望 DGC 活动的及时性有上限,则 这些属性可以设置得尽可能高,以使显式收集之间的时间有效地无限。

8.2.2 软引用

软引用在服务器虚拟机中的存活时间比在客户端中的时间长。

清除速率可以使用命令行选项来控制,该选项-XX:SoftRefLRUPolicyMSPerMB=指定对于堆中每兆字节的可用空间,软引用将保持活动状态(一旦不再强可达)的毫秒数 (ms)。默认值为每兆字节 1000 毫秒,这意味着对于堆中每兆字节的可用空间,软引用将存活(在收集到对象的最后一个强引用之后)1 秒。这是一个近似数字,因为软引用仅在垃圾收集期间被清除,这可能会偶尔发生。

8.2.3 类元数据

Java 类在 Java Hotspot VM 中有一个内部表示,称为类元数据

在 Java Hotspot VM 的先前版本中,类元数据是在所谓的永久代中分配的。从 JDK 8 开始永久代被删除类元数据被分配在本地内存中。默认情况下,可用于类元数据的本机内存是无限的。使用该选项-XX:MaxMetaspaceSize对用于类元数据的本机内存量设置上限

Java Hotspot VM 显式管理用于元数据的空间。从操作系统请求空间,然后分成块。类加载器从其块中为元数据分配空间(块绑定到特定的类加载器)。当为类加载器卸载类时,它的块被回收以供重用或返回给操作系统。元数据使用由 分配的空间mmap,而不是由分配的空间malloc。

如果-XX:UseCompressedOops打开并被-XX:UseCompressedClassesPointers使用,则本机内存的两个逻辑不同区域用于类元数据。与 Java 对象引用-XX:UseCompressedClassPointers一样,使用 32 位偏移量来表示 64 位进程中的类指针。-XX:UseCompressedOops为这些压缩类指针(32 位偏移)分配一个区域。区域的大小可以设置-XX:CompressedClassSpaceSize为默认为 1 GB。压缩类指针的空间保留为-XX:mmap初始化时分配的空间,并根据需要提交。-XX:MaxMetaspaceSize应用于提交的压缩类空间和其他类元数据的空间之和 。

当相应的 Java 类被卸载时,类元数据被释放。Java 类作为垃圾收集的结果被卸载,并且垃圾收集可能被诱导卸载类和释放类元数据。当为类元数据提交的空间达到某个级别(高水位标记)时,就会引发垃圾收集。在垃圾收集之后,高水位标记可能会根据从类元数据中释放的空间量来提高或降低。将提高高水位线,以免过早引发另一次垃圾收集。高水位线最初设置为命令行选项的值-XX:MetaspaceSize。它根据选项升高或降低,-XX:MaxMetaspaceFreeRatio并且-XX:MinMetaspaceFreeRatio. 如果类元数据可用的已提交空间占类元数据的总已提交空间的百分比大于-XX:MaxMetaspaceFreeRatio,则高水位线将降低。如果小于-XX:MinMetaspaceFreeRatio,则将提高高水位线。

为该选项指定更高的值, -XX:MetaspaceSize以避免为类元数据引发早期垃圾收集。为应用程序分配的类元数据量取决于应用程序,并且不存在用于选择 -XX:MetaspaceSize. 的默认大小 -XX:MetaspaceSize取决于平台,范围从 12 MB 到大约 20 MB。

有关用于元数据的空间的信息包含在堆的打印输出中。以下是典型输出:

[0,296s][info][gc,heap,exit] Heap
[0,296s][info][gc,heap,exit] garbage-first heap total 514048K, used 0K [0x00000005ca600000, 0x00000005ca8007d8, 0x00000007c0000000)
[0,296s][info][gc,heap,exit] region size 2048K, 1 young (2048K), 0 survivors (0K)
[0,296s][info][gc,heap,exit] Metaspace used 2575K, capacity 4480K, committed 4480K, reserved 1056768K
[0,296s][info][gc,heap,exit] class space used 238K, capacity 384K, committed 384K, reserved 1048576K

在以 开头的行中Metaspace,
该used值是用于加载的类的空间量
该capacity值是当前分配的块中可用于元数据的空间
该committed值是可用于块的空间量
该reserved值是为元数据保留(但不一定已提交)的空间量。
以 开头的行class space包含压缩类指针的元数据的相应值。

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

宋小生的博客

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

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

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

打赏作者

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

抵扣说明:

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

余额充值