Quarkus原生应用jvm.memory.used指标采集失败问题咨询
问题分析:Quarkus原生应用偶发
Failed to apply the value function for the gauge 'jvm.memory.used'错误 我们的Quarkus原生应用会偶发出现错误:Failed to apply the value function for the gauge 'jvm.memory.used',应用本身运行正常,错误无规律,每周或每月出现一次。应用在使用POI生成大型xlsx文件时内存消耗较高,但错误并非和业务执行直接关联——最近一次错误发生时,距离上一次业务执行已过去约30分钟。
我们需要明确:此问题属于框架缺陷(需上报)、开发问题(可修复/调优)还是正常现象?
使用技术栈
- Quarkus 3.8.5
- Java 17
该问题也在以下环境复现:
- Quarkus 3.8.5
- Java 21
- 构建环境:
GraalVM for JDK 21 Community 21.0.2 (Java version: 21.0.2+13, vendor version: GraalVM CE 21.0.2+13.1),基于镜像ghcr.io/graalvm/graalvm-community:21-ol7
错误堆栈
[io.mic.cor.ins.int.DefaultGauge] (executor-thread-348) Failed to apply the value function for the gauge 'jvm.memory.used'. Note that subsequent logs will be logged at debug level.: java.lang.IllegalArgumentException: committed = 1660640336 should be < max = 1659895808 at java.management@17.0.9/java.lang.management.MemoryUsage.<init>(MemoryUsage.java:166) at org.graalvm.nativeimage.builder/com.oracle.svm.core.genscavenge.AbstractMemoryPoolMXBean.memoryUsage(AbstractMemoryPoolMXBean.java:75) at org.graalvm.nativeimage.builder/com.oracle.svm.core.genscavenge.GenScavengeMemoryPoolMXBeans$EdenMemoryPoolMXBean.getUsage(GenScavengeMemoryPoolMXBeans.java:94) at io.micrometer.core.instrument.binder.jvm.JvmMemory.getUsage(JvmMemory.java:79) at io.micrometer.core.instrument.binder.jvm.JvmMemory.getUsageValue(JvmMemory.java:69) at io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics.lambda$bindTo$0(JvmMemoryMetrics.java:82) at io.micrometer.core.instrument.internal.DefaultGauge.value(DefaultGauge.java:53) at io.micrometer.prometheus.PrometheusMeterRegistry.lambda$newGauge$5(PrometheusMeterRegistry.java:338) at io.micrometer.prometheus.MicrometerCollector.collect(MicrometerCollector.java:75) at io.prometheus.client.Collector.collect(Collector.java:45) at io.prometheus.client.CollectorRegistry$MetricFamilySamplesEnumeration.findNextElement(CollectorRegistry.java:204) at io.prometheus.client.CollectorRegistry$MetricFamilySamplesEnumeration.nextElement(CollectorRegistry.java:219) at io.prometheus.client.CollectorRegistry$MetricFamilySamplesEnumeration.nextElement(CollectorRegistry.java:152) at io.prometheus.client.exporter.common.TextFormat.write004(TextFormat.java:71) at io.prometheus.client.exporter.common.TextFormat.writeFormat(TextFormat.java:53) at io.micrometer.prometheus.PrometheusMeterRegistry.scrape(PrometheusMeterRegistry.java:154) at io.micrometer.prometheus.PrometheusMeterRegistry.scrape(PrometheusMeterRegistry.java:149) at io.micrometer.prometheus.PrometheusMeterRegistry.scrape(PrometheusMeterRegistry.java:120) at io.quarkus.micrometer.runtime.export.handlers.PrometheusHandler.doHandle(PrometheusHandler.java:63) at io.quarkus.micrometer.runtime.export.handlers.PrometheusHandler.handle(PrometheusHandler.java:43) at io.quarkus.micrometer.runtime.export.handlers.PrometheusHandler.handle(PrometheusHandler.java:18) at io.vertx.ext.web.impl.BlockingHandlerDecorator.lambda$handle$0(BlockingHandlerDecorator.java:48) at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$1(ContextImpl.java:191) at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:279) at io.vertx.core.impl.ContextImpl.lambda$internalExecuteBlocking$2(ContextImpl.java:210) at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:582) at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538) at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29) at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.base@17.0.9/java.lang.Thread.run(Thread.java:840) at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:807) at org.graalvm.nativeimage.builder/com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:210)
错误发生时监控数据
jvm_memory_used_bytes (eden space)从~1.55 GB降至~14.8 MB
jvm_memory_used_bytes (old generation space)从~232.67 MB升至~251.04 MB
问题定性与建议
从错误堆栈和官方问题记录来看,这是GraalVM原生镜像的框架缺陷,并非应用开发问题或正常现象:
- 错误根源是GraalVM的内存池MXBean实现中,在垃圾回收后的并发统计场景下,出现了
committed内存值大于max的情况,违反了MemoryUsage的参数校验规则。 - 该问题属于底层运行时的并发统计bug,和应用业务逻辑无直接关联——即使业务执行结束后,监控指标采集时仍可能触发,且已在GraalVM和Quarkus的官方问题追踪系统中被记录。
处理建议
- 无需修改应用代码,关注官方修复进展,等待GraalVM或Quarkus发布包含修复的版本后升级。
- 若错误日志影响排查,可临时调整日志级别,将
io.micrometer.core.instrument.internal.DefaultGauge的日志级别设为DEBUG(错误提示中已说明后续日志会自动降级)。
内容的提问来源于stack exchange,提问作者gian1200
相关产品推荐
相关产品推荐

