Spring Boot JVM Metrics:jvm_memory_max_bytes值为-1的原因探究
G1收集器下JVM内存指标max值为-1的含义与原因
问题背景
在JDK8环境使用G1垃圾收集器时,/actuator/prometheus输出的jvm_memory_max_bytes指标中,G1 Survivor Space、G1 Eden Space、Metaspace的max值为-1.0。相关指标输出示例:
# HELP jvm_memory_max_bytes The maximum amount of memory in bytes that can be used for memory management # TYPE jvm_memory_max_bytes gauge jvm_memory_max_bytes{area="heap",id="G1 Survivor Space",} -1.0 jvm_memory_max_bytes{area="heap",id="G1 Old Gen",} 1.073741824E9 jvm_memory_max_bytes{area="nonheap",id="Metaspace",} -1.0 jvm_memory_max_bytes{area="heap",id="G1 Eden Space",} -1.0 jvm_memory_max_bytes{area="nonheap",id="Code Cache",} 2.5165824E8 jvm_memory_max_bytes{area="nonheap",id="Compressed Class Space",} 1.073741824E9
-1值的含义
在Spring Boot Actuator依赖的Micrometer指标体系中,jvm_memory_max_bytes的-1.0代表该内存区域没有固定的预设最大内存限制,其实际可用的内存上限会根据JVM运行时的负载、整体内存使用情况动态调整。
出现原因
G1收集器的堆分区动态调整特性(Eden/Survivor区域)
G1是基于Region的分区式垃圾收集器,它将整个堆划分为多个大小均等的Region块:
- Eden和Survivor区域并非传统收集器中固定大小的连续内存块,而是由若干个Region动态组合而成。
- JVM不会为这两个区域设置固定的最大内存值,而是在运行过程中根据GC效率、对象存活情况,动态调整分配给它们的Region数量,因此指标中max值显示为-1,这是JDK8下G1的正常表现。
Metaspace的无默认上限机制
JDK8中Metaspace替代了永久代,它的内存管理特性:
- 默认情况下,Metaspace没有固定的最大内存限制,JVM会根据类加载的需求自动扩容(直到耗尽系统可用内存)。
- 只有通过
-XX:MaxMetaspaceSize参数显式配置最大值后,jvm_memory_max_bytes指标才会显示对应的固定值,否则默认显示为-1。
内容的提问来源于stack exchange,提问作者Kyle Chou
相关产品推荐
相关产品推荐

