Java 为什么垃圾收集日志元空间值与提供的标志不同?

Java 为什么垃圾收集日志元空间值与提供的标志不同?,java,garbage-collection,java-8,metaspace,Java,Garbage Collection,Java 8,Metaspace,我正在Java 8上运行带有以下标志的服务器应用程序: -XX:GCLogFileSize=2097152 -XX:InitialBootClassLoaderMetaspaceSize=33554432 -XX:InitialHeapSize=1610612736 -XX:MaxHeapSize=1610612736 -XX:MaxMetaspaceSize=1073741824 -XX:MetaspaceSize=536870912 -XX:NumberOfGCLogFiles=5 -XX:

我正在Java 8上运行带有以下标志的服务器应用程序:

-XX:GCLogFileSize=2097152 -XX:InitialBootClassLoaderMetaspaceSize=33554432 -XX:InitialHeapSize=1610612736 -XX:MaxHeapSize=1610612736 -XX:MaxMetaspaceSize=1073741824 -XX:MetaspaceSize=536870912 -XX:NumberOfGCLogFiles=5 -XX:+PrintGC -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseGCLogFileRotation -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
元空间的起始值为512m,最大值为1gb

在GC日志中,我看到了与上述标志值不同的元空间值。我的日志示例如下:

{Heap before GC invocations=1 (full 0):
 PSYoungGen      total 458752K, used 393216K [0x00000000e0000000, 0x0000000100000000, 0x0000000100000000)
  eden space 393216K, 100% used [0x00000000e0000000,0x00000000f8000000,0x00000000f8000000)
  from space 65536K, 0% used [0x00000000fc000000,0x00000000fc000000,0x0000000100000000)
  to   space 65536K, 0% used [0x00000000f8000000,0x00000000f8000000,0x00000000fc000000)
 ParOldGen       total 1048576K, used 0K [0x00000000a0000000, 0x00000000e0000000, 0x00000000e0000000)
  object space 1048576K, 0% used [0x00000000a0000000,0x00000000a00003a0,0x00000000e0000000)
 Metaspace       used 26975K, capacity 54120K, committed 54400K, reserved 1114112K
  class space    used 3346K, capacity 4426K, committed 4480K, reserved 1048576K
2016-12-21T16:41:10.569+0300: 1.423: [GC (GCLocker Initiated GC) [PSYoungGen: 393216K->29645K(458752K)] 393216K->29734K(1507328K), 0.0241803 secs] [Times: user=0.11 sys=0.00, real=0.02 secs] 
Heap after GC invocations=1 (full 0):
 PSYoungGen      total 458752K, used 29645K [0x00000000e0000000, 0x0000000100000000, 0x0000000100000000)
  eden space 393216K, 0% used [0x00000000e0000000,0x00000000e0000000,0x00000000f8000000)
  from space 65536K, 45% used [0x00000000f8000000,0x00000000f9cf3460,0x00000000fc000000)
  to   space 65536K, 0% used [0x00000000fc000000,0x00000000fc000000,0x0000000100000000)
 ParOldGen       total 1048576K, used 88K [0x00000000a0000000, 0x00000000e0000000, 0x00000000e0000000)
  object space 1048576K, 0% used [0x00000000a0000000,0x00000000a00163b0,0x00000000e0000000)
 Metaspace       used 26975K, capacity 54120K, committed 54400K, reserved 1114112K
  class space    used 3346K, capacity 4426K, committed 4480K, reserved 1048576K
}
所以我的问题是:为什么我在GC日志中看不到metaspace的512m和1gb值?日志值是否与标志没有直接关系?

如中所述:

-XX:MetaspaceSize=size 设置分配的类元数据空间的大小,该空间将在第一次超出时触发垃圾回收。垃圾收集的此阈值根据使用的元数据量而增加或减少。默认大小取决于平台

换句话说,它没有指定初始大小,而是指定第一次gc阈值,因此它与您观察到的没有完整gc的行为相匹配,而实际的元空间大小小于指定的大小


一旦第一次超过阈值,JVM可能会根据实际使用情况选择一个新的阈值。

我通常建议开发人员删除所有他们不了解的选项。JVM有合理的默认值,假设知道一个比JVM更好的值是没有意义的,甚至不理解该选项的实际含义。问题是,如果我不设置元空间标志,服务器在启动时会使用许多完整的gc。我相信这是因为元空间变满了,因为64位服务器的默认值是21mb。当我设置标志时,完全gc不会发生。我的问题解决了。但是我仍然想理解日志和标志的不一致性。
-XX:MetaspaceSize
没有指定初始大小,而是指定触发gc的阈值。因此,只要实际的元空间大小小于此值,它就不会触发gc。但这个阈值并不是恒定的。在运行时,JVM可以根据实际使用情况选择新值。但无论如何,为什么服务器的启动时间如此重要?为长时间的性能调整参数不是更有意义吗?关于服务器启动时间,您是对的,这并不是那么重要,我只是在调整,希望在启动时摆脱完整的gc,并在这一点上感到好奇。你最后的评论解释了我对国旗的误解,谢谢你。我可以接受它,如果你可以添加它作为答案。