JVM元空间在调整大小时是否总是触发GC
Does JVM metaspace always trigger GC when resizing
对于 Java 8
之后的 JVM
- 当metaspace的大小>
-XX:metaspaceSize
时,会触发gc。
- 无论
-XX:metaspaceSize
和-XX:maxMetaspaceSize
如何配置,元空间的初始大小在64位服务器上通常是一个固定值(20.8M)。
- JVM 将在接近当前容量时自动调整元空间大小。
- 那么,如果
-XX:metaspaceSize
例如是20G,当前metaspace的大小是18M,需要分配大量的新对象(大约100M),JVM必须为这些新的对象调整metaspace的大小对象,JVM 会在调整大小之前触发完整的 GC 吗?
您可以配置元空间大小,但 JVM 可以根据相关平台增加或减少大小。
参见 Oracle docs.
-XX:MetaspaceSize=size
Sets the size of the allocated class metadata space that will trigger a garbage collection the first time it is exceeded. This threshold for a garbage collection is increased or decreased depending on the amount of metadata used. The default size depends on the platform.
首先,"the size of the metaspace"是模棱两可的,因此没有上下文就没有意义。至少有五个指标:reserved、committed、capacity 和 used 内存如 中所述,以及 high-water 标记,也称为 capacity_until_gc.
Metaspace 不仅仅是一个连续的内存区域,所以它不会按常识调整大小。相反,当分配发生时,上述一个或多个指标会发生变化。
- 在最快的路径上,从当前块中分配一块元数据。
used
本例内存增加,仅此而已。
- 如果当前块中没有足够的空间,JVM 会搜索可能空闲的现有块。如果成功重用块,
capacity
增加。直到此时才发生 GC。
- 如果没有空闲块,JVM 会尝试提交更多内存,除非新的
committed
大小会超过 capacity_until_gc
。
- 如果达到
capacity_until_gc
阈值,JVM 将触发 GC 周期。
- 如果 GC 没有释放足够的内存,high-water 标记会增加,以便分配另一个虚拟 Space。
GC后high-water标记值根据following JVM flags调整:
-XX:MinMetaspaceFreeRatio
(用于计算metaspace容量中需要多少空闲space来决定增加多少HWM);
-XX:MaxMetaspaceFreeRatio
(用于决定在降低 HWM 之前元space 容量中需要多少空闲 space);
-XX:MinMetaspaceExpansion
(Metaspace的最小扩展字节数);
-XX:MaxMetaspaceExpansion
(没有full GC的Metaspace的最大扩展)。
TL;DR没那么简单。 JVM 绝对可以在不触发 GC 的情况下提交更多 Metaspace 内存。但是,当达到HWM时,会触发GC,根据人机工程学策略重新计算HWM。
对于 Java 8
之后的 JVM- 当metaspace的大小>
-XX:metaspaceSize
时,会触发gc。 - 无论
-XX:metaspaceSize
和-XX:maxMetaspaceSize
如何配置,元空间的初始大小在64位服务器上通常是一个固定值(20.8M)。 - JVM 将在接近当前容量时自动调整元空间大小。
- 那么,如果
-XX:metaspaceSize
例如是20G,当前metaspace的大小是18M,需要分配大量的新对象(大约100M),JVM必须为这些新的对象调整metaspace的大小对象,JVM 会在调整大小之前触发完整的 GC 吗?
您可以配置元空间大小,但 JVM 可以根据相关平台增加或减少大小。 参见 Oracle docs.
-XX:MetaspaceSize=size
Sets the size of the allocated class metadata space that will trigger a garbage collection the first time it is exceeded. This threshold for a garbage collection is increased or decreased depending on the amount of metadata used. The default size depends on the platform.
首先,"the size of the metaspace"是模棱两可的,因此没有上下文就没有意义。至少有五个指标:reserved、committed、capacity 和 used 内存如
Metaspace 不仅仅是一个连续的内存区域,所以它不会按常识调整大小。相反,当分配发生时,上述一个或多个指标会发生变化。
- 在最快的路径上,从当前块中分配一块元数据。
used
本例内存增加,仅此而已。 - 如果当前块中没有足够的空间,JVM 会搜索可能空闲的现有块。如果成功重用块,
capacity
增加。直到此时才发生 GC。 - 如果没有空闲块,JVM 会尝试提交更多内存,除非新的
committed
大小会超过capacity_until_gc
。 - 如果达到
capacity_until_gc
阈值,JVM 将触发 GC 周期。 - 如果 GC 没有释放足够的内存,high-water 标记会增加,以便分配另一个虚拟 Space。
GC后high-water标记值根据following JVM flags调整:
-XX:MinMetaspaceFreeRatio
(用于计算metaspace容量中需要多少空闲space来决定增加多少HWM);-XX:MaxMetaspaceFreeRatio
(用于决定在降低 HWM 之前元space 容量中需要多少空闲 space);-XX:MinMetaspaceExpansion
(Metaspace的最小扩展字节数);-XX:MaxMetaspaceExpansion
(没有full GC的Metaspace的最大扩展)。
TL;DR没那么简单。 JVM 绝对可以在不触发 GC 的情况下提交更多 Metaspace 内存。但是,当达到HWM时,会触发GC,根据人机工程学策略重新计算HWM。