为AWS Lambda构建Micronaut应用GraalVM原生镜像失败求助
问题描述
执行命令 ./gradlew clean buildNativeLambda -Pmicronaut.runtime=lambda 构建AWS Lambda用的Micronaut GraalVM原生镜像时,内存和CPU占用飙升至100%,30-40分钟后构建失败,抛出死锁相关栈跟踪:
=== Image generator watchdog detected no activity. This can be a sign of a deadlock during image building. Dumping all stack traces. Current time: Mon Oct 03 10:48:30 UTC 2022 "main" Id=1 in RUNNABLE at app//com.oracle.graal.pointsto.flow.OffsetStoreTypeFlow$AbstractUnsafeStoreTypeFlow.handleUnsafeAccessedFields(OffsetStoreTypeFlow.java:244) at app//com.oracle.graal.pointsto.flow.OffsetStoreTypeFlow$UnsafeStoreTypeFlow.onObservedUpdate(OffsetStoreTypeFlow.java:292) at app//com.oracle.graal.pointsto.flow.TypeFlow.update(TypeFlow.java:552) at app//com.oracle.graal.pointsto.PointsToAnalysis$1.run(PointsToAnalysis.java:631) at app//com.oracle.graal.pointsto.util.CompletionExecutor.executeCommand(CompletionExecutor.java:193) at app//com.oracle.graal.pointsto.util.CompletionExecutor.lambda$executeService$0(CompletionExecutor.java:177) at app//com.oracle.graal.pointsto.util.CompletionExecutor$$Lambda$677/0x00000007c3273440.run(Unknown Source) at java.base@11.0.15/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426) at java.base@11.0.15/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) at java.base@11.0.15/java.util.concurrent.ForkJoinPool.awaitQuiescence(ForkJoinPool.java:2984) at app//com.oracle.graal.pointsto.util.CompletionExecutor.complete(CompletionExecutor.java:243) at app//com.oracle.graal.pointsto.PointsToAnalysis.doTypeflow(PointsToAnalysis.java:688) at app//com.oracle.graal.pointsto.PointsToAnalysis.finish(PointsToAnalysis.java:676) at app//com.oracle.graal.pointsto.PointsToAnalysis.runAnalysis(PointsToAnalysis.java:732) at app//com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:723) at app//com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:558) at app//com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:515) at app//com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:407) at app//com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:585) at app//com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:128) at app//com.oracle.svm.hosted.NativeImageGeneratorRunner$JDK9Plus.main(NativeImageGeneratorRunner.java:615) "Reference Handler" Id=2 in RUNNABLE at java.base@11.0.15/java.lang.ref.Reference.processPendingReferences(Reference.java:261) at java.base@11.0.15/java.lang.ref.Reference$ReferenceHandler.run(Reference.java:213) "Finalizer" Id=3 in WAITING on lock=java.lang.ref.ReferenceQueue$Lock@16974940 at java.base@11.0.15/java.lang.Object.wait(Native Method) at java.base@11.0.15/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155) at java.base@11.0.15/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:176) at java.base@11.0.15/java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:170) "Signal Dispatcher" Id=4 in RUNNABLE "JVMCI-native CompilerThread0" Id=6 in RUNNABLE "Common-Cleaner" Id=9 in RUNNABLE at java.base@11.0.15/java.lang.invoke.MethodHandleNatives.clearCallSiteContext(Native Method) at java.base@11.0.15/java.lang.invoke.MethodHandleNatives$CallSiteContext.run(MethodHandleNatives.java:92) at java.base@11.0.15/jdk.internal.ref.CleanerImpl$PhantomCleanableRef.performCleanup(CleanerImpl.java:186) at java.base@11.0.15/jdk.internal.ref.PhantomCleanable.clean(PhantomCleanable.java:133) at java.base@11.0.15/jdk.internal.ref.CleanerImpl.run(CleanerImpl.java:150) at java.base@11.0.15/java.lang.Thread.run(Thread.java:829) at java.base@11.0.15/jdk.internal.misc.InnocuousThread.run(InnocuousThread.java:161) "native-image pid watcher" Id=13 in TIMED_WAITING on lock=java.util.TaskQueue@1850a5e2 at java.base@11.0.15/java.lang.Object.wait(Native Method) at java.base@11.0.15/java.util.TimerThread.mainLoop(Timer.java:553) at java.base@11.0.15/java.util.TimerThread.run(Timer.java:506) "Libgraal MBean Registration" Id=22 in TIMED_WAITING at java.base@11.0.15/java.lang.Thread.sleep(Native Method) at platform/jdk.internal.vm.compiler.management/org.graalvm.compiler.hotspot.management.Factory.run(Factory.java:111) "ForkJoinPool.commonPool-worker-5" Id=24 in TIMED_WAITING on lock=java.util.concurrent.ForkJoinPool@18cbf3e3 at java.base@11.0.15/jdk.internal.misc.Unsafe.park(Native Method) at java.base@11.0.15/java.util.concurrent.locks.LockSupport.parkUntil(LockSupport.java:275) at java.base@11.0.15/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1619) at java.base@11.0.15/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183) "ForkJoinPool.commonPool-worker-15" Id=29 in WAITING on lock=java.util.concurrent.ForkJoinPool@18cbf3e3 at java.base@11.0.15/jdk.internal.misc.Unsafe.park(Native Method) at java.base@11.0.15/java.util.concurrent.locks.LockSupport.park(LockSupport.java:194) at java.base@11.0.15/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1628) at java.base@11.0.15/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
依赖配置(build.gradle)
dependencies { annotationProcessor('io.micronaut:micronaut-inject-java') annotationProcessor("io.micronaut.data:micronaut-data-processor") annotationProcessor("io.micronaut:micronaut-http-validation") implementation("io.micronaut:micronaut-http-client") implementation("io.micronaut:micronaut-jackson-databind") implementation("jakarta.annotation:jakarta.annotation-api") runtimeOnly("ch.qos.logback:logback-classic") // runtimeOnly('org.slf4j:log4j-over-slf4j:2.0.2') implementation("io.micronaut:micronaut-validation") implementation("io.micronaut.aws:micronaut-function-aws-custom-runtime") implementation("io.micronaut.data:micronaut-data-hibernate-jpa") implementation("io.micronaut.sql:micronaut-jdbc-hikari") runtimeOnly("mysql:mysql-connector-java") compileOnly("org.graalvm.nativeimage:svm") implementation("io.micronaut.aws:micronaut-function-aws") implementation("io.micronaut.aws:micronaut-function-aws-custom-runtime") implementation group: 'org.json', name: 'json', version: "${orgJsonVersion}" implementation group: 'org.apache.poi', name: 'poi', version: "${poiVersion}" implementation group: 'org.apache.poi', name: 'poi-ooxml', version: "${poiVersion}" implementation group: 'org.apache.commons', name: 'commons-lang3', version: "${apacheCommons}" implementation group: 'com.google.code.gson', name: 'gson', version: "${googleGson}" // implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation', version: "${springValidation}" implementation group: 'org.eclipse.persistence', name: 'eclipselink', version: "${eclipseLink}" // compileOnly group: 'javax.servlet', name: 'servlet-api', version: "${servletApi}" implementation("org.apache.velocity:velocity:${velocity}") { exclude group: 'log4j', module: 'log4j' } implementation("org.apache.velocity:velocity-tools:${velocityTools}") { exclude group: 'log4j', module: 'log4j' } implementation group: 'org.apache.kafka', name: 'kafka-clients', version: "${kafkaClient}" implementation group: 'com.google.guava', name: 'guava', version: "${googleGuava}" }
构建配置(build.gradle)
tasks.named("dockerfileNative") { args( "-XX:MaximumHeapSizePercent=80", "-Dio.netty.allocator.numDirectArenas=0", "-Dio.netty.noPreferDirect=true" ) } graalvmNative.binaries.all { buildArgs.add("--no-server -J-Xmx12g -J-Xms4g") }
系统配置
- 内存: 16GB
- CPU: 11代i5
- 操作系统: Windows 10
解决方案
1. 清理冗余与冲突依赖
- 删除重复声明的
micronaut-function-aws-custom-runtime依赖,避免GraalVM分析冗余类 - 移除EclipseLink依赖:同时引入Hibernate和EclipseLink两个JPA实现会大幅增加分析负担,Lambda场景保留Hibernate即可
2. 优化GraalVM构建参数
修改graalvmNative配置,启用缓存并调整内存分配:
graalvmNative.binaries.all { buildArgs.add("-J-Xmx10g -J-Xms6g") // 16GB内存下分配10G给构建,避免系统内存耗尽 buildArgs.add("--server") // 启用构建缓存,减少重复分析耗时 buildArgs.add("--no-fallback") // 强制原生镜像构建,避免回退到解释模式 buildArgs.add("-H:+PrintAnalysisStatistics") // 打印分析统计,定位性能瓶颈 }
若Windows系统卡顿,可先尝试-J-Xmx8g,再逐步调整。
3. 处理GraalVM不友好的依赖
- Apache POI、Velocity大量使用反射和Unsafe操作,若Lambda不需要则直接移除;必须保留时,需添加对应的GraalVM元数据(
reflect-config.json、resource-config.json) - Kafka Clients若不是Lambda必需功能,建议移除,缩小分析范围
4. 优化系统环境
- 关闭Windows后台不必要程序,释放内存和CPU资源
- 切换至高性能电源计划,确保CPU性能不被限制
- 优先使用WSL2构建:GraalVM在Linux环境下的稳定性和性能优于Windows
5. 升级框架版本
使用GraalVM 22.3+和Micronaut 3.8+版本,这些版本修复了大量原生镜像构建的死锁和性能问题,兼容性更好。
内容的提问来源于stack exchange,提问作者Jignesh M. Khatri
相关产品推荐
相关产品推荐

