分配的元空间大于 MaxMetaspaceSize

Metaspace allocated more then MaxMetaspaceSize

在Java8,我运行GC登录我的服务,通过GCeasy我看到metaspace分配了1GB,而峰值在40m左右,为什么分配了1GB ?

我玩这些标志并添加了“-XX:MaxMetaspaceSize=10M”。

然后我得到了 java.lang.OutOfMemoryError: Metaspace,正如预期的那样,但我仍然在 GC 日志上看到分配了 1 GB。 日志中有错误吗?或者我遗漏了什么。

我 运行 在 GC 日志文件上 grep Metaspace 并得到以下输出:

命令行标志:-XX:CompressedClassSpaceSize=2097152 -XX:+DisableExplicitGC -XX:GCLogFileSize=104857600 -XX:InitialHeapSize=536870912 -XX:MaxHeapSize=536870912 -XX:MaxMetaspaceSize=1045760[ 30=] -XX:MetaspaceSize=10485760 -XX:NumberOfGCLogFiles=10 -XX:+PrintGC -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:ReservedCodeCacheSize=134217728 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseGCLogFileRotation -XX:+UseParallelGC

2020-05-19T16:38:18.359+0000:0.837: [Full GC(元数据 GC 阈值)[PSYoungGen: 7298K->0K(153088K)] [ParOldGen: 8K->6944K(349696K)] 7306K ->6944K(502784K),[元空间:9975K->9975K(1058816K)],0.0249384 秒] [时间:用户=0.08 系统=0.01,实际=0.02 秒]

2020-05-19T16:38:18.386+0000:0.864: [Full GC(元数据 GC 阈值)[PSYoungGen: 0K->0K(153088K)] [ParOldGen: 6944K->6944K(349696K)] 6944K ->6944K(502784K),[元空间:9975K->9975K(1058816K)],0.0129850 秒] [时间:用户=0.04 系统=0.00,实际=0.01 秒]

2020-05-19T16:38:18.400+0000:0.879: [Full GC(最后一次收集)[PSYoungGen: 0K->0K(153088K)] [ParOldGen: 6944K->6816K(349696K)] 6944K ->6816K(502784K),[元空间:9975K->9965K(1058816K)],0.0252318 秒] [时间:用户=0.07 系统=0.00,实际=0.03 秒]

答案基本上是 ,虽然理解起来并不简单。

MaxMetaspaceSize 限制了 committed 内存,而您的 GC 日志实际上打印了 reserved 内存。因此保留:1058816K,已提交:9975K,根据您的日志。保留内存根本不需要由交换或实际 RAM 支持,因此通常非常大。

这就是为什么您在 GC log 中看到那些大数字的原因。