Java虚拟机(JVM)调整GC

在上一章中,我们了解了各种代GC。在本章中将讨论如何调整GC。

堆大小

堆大小是Java应用程序性能的重要因素。如果它太小,那么它将经常被填充,因此,必须经常由GC收集。另一方面,如果只增加堆的大小,虽然它需要不那么频繁地收集,但是暂停的长度会增加。

此外,增加堆大小会对底层操作系统造成严重损害。使用分页,操作系统使应用程序看到的内存比实际可用内存多得多。操作系统通过使用磁盘上的一些交换空间来管理它,将程序的非活动部分复制到其中。当需要这些部分时,OS会将它们从磁盘复制回内存。

假设一台机器有8G的内存,而JVM看到16G的虚拟内存,JVM不会知道系统上实际上只有8G可用。它只会从操作系统请求16G,一旦获得该内存,它将继续使用它。操作系统必须交换大量数据,这对系统造成了巨大的性能损失。

然后是在这种虚拟内存的完整GC期间发生的暂停。由于GC将在整个堆上进行收集和压缩,因此必须等待很多时间才能将虚拟内存换出磁盘。在并发收集器的情况下,后台线程将不得不等待将数据从交换空间复制到内存。

所以这里是应该如何决定最佳堆大小的问题。第一条规则是永远不要求OS比实际存在的内存更多。这将完全防止频繁交换的问题。如果机器安装并运行了多个JVM,那么它们所有组合的总内存请求小于系统中存在的实际RAM。

可以使用两个标志来控制JVM的内存请求大小 -

  • -XmsN - 控制请求的初始内存。
  • -XmxN - 控制可以请求的最大内存。

这两个标志的默认值取决于底层操作系统。例如,对于在MacOS上运行的64b JVM,-XmsN = 64M,-XmxN =最小1G或总物理内存的1/4。

请注意,JVM可以自动在两个值之间进行调整。例如,如果它注意到GC发生太多,只要它低于-XmxN并且满足所需的性能目标,它就会继续增加内存大小。

如果您确切知道应用程序需要多少内存,则可以设置-XmsN = -XmxN。在这种情况下,JVM不需要计算堆的“最佳”值,因此GC过程变得更有效。

代大小

可以决定要为YG分配多少堆,以及要为OG分配多少堆。这两个值都以下列方式影响应用程序的性能。

如果YG的尺寸非常大,那么它的收集频率会降低。这将导致更少数量的对象被提升为OG。另一方面,如果过多地增加OG的大小,那么收集和压缩它会花费太多时间,这会导致长时间的STW暂停。因此,用户必须在这两个值之间找到平衡。

以下是可用于设置这些值的标志 -

  • -XX:NewRatio = N:YG与OG的比率(默认值= 2);
  • -XX:NewSize = N:YG的初始大小;
  • -XX:MaxNewSize = N:YG的最大尺寸;
  • -XmnN:使用此标志将NewSizeMaxNewSize设置为相同的值;

YG的初始大小由给定公式的NewRatio值决定 -

(total heap size) / (newRatio + 1)

由于newRatio的初始值为2,因此上述公式将YG的初始值赋予总堆大小的1/3。始终可以通过使用NewSize标志显式指定YG的大小来覆盖此值。此标志没有任何默认值,如果没有明确设置,YG的大小将继续使用上面的公式计算。

Permagen和Metaspace

permagen和元空间(Metaspace)是堆区域,JVM保存类的元数据。这个空间在Java 7中称为“permagen”,在Java 8中,它被称为“metaspace”。编译器和运行时使用此信息。

可以使用以下标志控制permagen的大小:-XX:PermSize = N-XX:MaxPermSize = N。可以使用以下方法控制元空间的大小:-XX:Metaspace- Size = N-XX:MaxMetaspaceSize = N

在未设置标志值时,如何管理permagen和元空间存在一些差异。默认情况下,两者都具有默认的初始大小。但是,虽然元空间可以占用所需的堆,但permagen可以占用不超过默认的初始值。例如,64b JVM具有82M的堆空间作为最大permagen大小。

请注意,由于元空间可以占用无限量的内存,除非另有指定,否则可能会出现内存不足错误。每当调整这些区域的大小时,都会发生完整的GC。因此,在启动期间,如果有许多类被加载,则元空间可以继续调整大小,从而每次都生成一个完整的GC。因此,如果初始元空间大小太小,则需要花费大量时间来启动大型应用程序。增加初始大小是一个好主意,因为它可以减少启动时间。

尽管permagen和metaspace保存了类元数据,但它并不是永久性的,并且GC会回收空间,就像对象一样。这通常用于服务器应用程序。无论何时对服务器进行新的部署,都必须清除旧的元数据,因为新的类加载器现在需要空间。GC释放了这个空间。


上一篇:Java虚拟机(JVM)分代GC

下一篇:Java虚拟机(JVM)内存泄漏

关注微信小程序
程序员编程王-随时随地学编程

扫描二维码
程序员编程王

扫一扫关注最新编程教程