设置 MetaspaceSize 的准则 - java 8

64 位服务器的 MetaspaceSize 的默认值是什么?我在官方文档中找不到它。

我观察到,在服务器JVM进程中,有时GC频率会变得很高并且不断增长。如果我重新启动该服务几次,它将恢复稳定。我认为这是由于JRE升级。

JVM 堆最大大小设置为 6GB,但当出现此问题时,我们看到仅使用 3GB 堆。元空间增长很少,几乎总是满的。我尝试将元空间增加到1GB,它提高了吞吐量。

我认为正在发生的事情是,默认情况下,Metaspace被设置为一个非常低的值,因此GC开始发挥作用。每次GC发生时,高水位线都会持续增加(再次以非常低的量增加)。

我想设置MetaspaceSize(不确定当前值是多少)。

Oracle文档表示,没有指南可以知道将MetaspaceSize设置为什么。但是有没有办法找出将其设置为的正确值?

我从Oracle文档中得到的一个提示是这样的:

If the committed space available for class metadata as a percentage of the total committed space for class metadata is greater than MaxMetaspaceFreeRatio, then the high-water mark will be lowered. If it is less than MinMetaspaceFreeRatio, then the high-water mark will be raised.

但仍然无法弄清楚如何稳定GC。我有三个问题:

  1. 64 位服务器上的默认 MetaspaceSize 是什么?
  2. 默认比率是多少:MaxMetaspaceFreeRatio,MinMetaspaceFreeRatio设置为?答:它显示最小值为 40,最大值为 70
  3. 如何决定元空间大小值?

答案 1

MetaspaceSize是将触发时的值,它不是初始空间也不是最大空间。Full GC

它的默认值是(至少在 to 上):20MBjdk-8jdk-13

java -XX:+PrintFlagsFinal -version | grep MetaspaceSize

将产生:

size_t MetaspaceSize = 21807104 // 20MB

这意味着当达到时会被触发,如果你能避免它,那将是好的。Metaspace20MBFull GC

考虑到元数据空间可以容纳多少数据(方法,注释等),在我看来,这是一个非常小的值。不幸的是,选择正确的值并不容易。20MB

您有两个选项,启用 gc 日志记录并让应用程序运行一段时间,然后查找如下实例:-Xlog:gc

[Full GC (Metadata GC Threshold) ...]

并从中了解您需要设置的内容以及如何设置。

或者通过以下方式开始该过程:

java -XX:NativeMemoryTracking=detail

连接到通过 :PID

jcmd <YourJVMPID> VM.metaspace

并找到这样的行:

 Virtual space:
    Non-class space:        8.00 MB reserved,       4.25 MB ( 53%) committed
    Class space:            1.00 GB reserved,     512.00 KB ( <1%) committed
    Both:                   1.01 GB reserved,       4.75 MB ( <1%) committed

恕我直言,在应用程序运行至少一天后获取值。Non-class space

还有关于 如何控制 ,您可以像这样找到:Metaspace

java -XX:+PrintFlagsFinal -version | grep Metaspace

答案 2

我认为最有趣的问题是#3,所以我先回答这个问题。我的做法是使用以下设置在打开gc日志记录的情况下运行我的应用程序24小时:

-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintGCCause
-XX:+PrintTenuringDistribution
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCApplicationConcurrentTime
-Xloggc:gc.log

然后我做了这个:

grep Metaspace gc.log

并看到“使用”值迅速增长到80M...所以我将MetaspaceSize设置为100M

-XX:MetaspaceSize=100M

瞧 - 由于元空间,没有更多的gcs。

看起来@Pillar的评论几乎回答了您的前2个问题,即如何确定实现的默认Metaspace设置...为了完整起见,我将在此处包含它:

java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version -XX:+UseG1GC | grep Metaspace

从技术上讲,@Pillar的评论并没有告诉你任何64位服务器的默认Metaspace大小,但这是因为你的第一个问题有点误导,因为根据文档,这些默认值因实现而异。

看:

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/considerations.html

具体来说,底部的部分显示“MetaspaceSize的默认大小取决于平台,范围从12 MB到大约20 MB”


推荐