
GraalVM Native Image 构建选项完全指南从 -H:/ -R: 前缀体系到 -H:Preserve 与系统属性【免费下载链接】graalGraalVM compiles applications into native executables that start instantly, scale fast, and use fewer compute resources 项目地址: https://gitcode.com/gh_mirrors/gr/graalNative Image 是 GraalVM 提供的 AOT提前编译技术可将 Java 应用编译为启动迅速、资源占用更低的原生可执行文件。本指南围绕 docs/reference-manual/native-image/BuildOptions.md 展开系统梳理native-image构建器的全部命令行选项体系——从-H:hosted与-R:runtime选项前缀的语义区别到完整的 Build Options 表格解读再到-H:Preserve、Graph Dumping、系统属性等实用技巧。读完本文你将能够独立配置一次完整的 Native Image 构建理解每个关键选项的默认值与底层行为并能借助源码定位选项的具体实现。选项总览四类查询入口与两类语义前缀Native Image 的选项体系可以通过四个命令入口快速浏览命令作用native-image --help查看 Build Options标准构建选项帮助native-image --help-extra查看 Extra Build Options额外构建选项帮助native-image --expert-options查看 Expert Options专家选项帮助native-image --print-options以表格形式输出全部可用选项支持--print-optionsmdMarkdown与--print-optionsjson机器可读 JSON其中--print-options是获取最新、最权威选项清单的最佳途径——它直接从源码中的选项注册信息动态生成表格避免了手工维护文档的重复与滞后源码实现可参见 CommonOptions.java 中基于Option注解的选项声明模式。选项的数量与具体内容随 GraalVM 版本而变化但所有选项在语义上可以归为两大类Hosted Options-H:前缀用于配置构建过程本身并为运行时行为设置默认值。例如-H:MaxHeapSize2g即为生成的原生可执行文件设置默认最大堆大小。Runtime Options-R:前缀在构建时以-R:前缀为原生二进制提供显式的运行时初始值而在程序运行时这类选项的默认前缀是-XX:注意-XX:是应用层面的约定并非 Native Image 强制规定。在绝大多数场景下使用-H:选项即可同时配置构建期行为和运行时默认值无需刻意区分构建期与运行期配置。源码视角Hosted 与 Runtime 选项的实现机制从源码结构看这一双前缀体系并非简单的字符串约定而是由两套独立的选项存储机制支撑。在 package-info.java 中对此有明确说明Hosted 选项使用HostedOptionKey定义其值由HostedOptionValues维护。它们在运行期不可更改而是被保证在镜像中常量折叠constant fold——这是通过HostedOptionKey#getValue()上的Fold注解实现的。Runtime 选项使用RuntimeOptionKey定义其值由RuntimeOptionValues维护可以在运行期修改RuntimeOptionParser#parseAndConsumeAllOptions是运行期解析选项的便捷入口。由于 Graal 编译器本身是无状态的每次编译可用独立的OptionValues配置访问一个 Graal 选项时需显式指定上述两套值中的一套HostedOptionValues#singleton()或RuntimeOptionValues#singleton()。例如-H:MaxHeapSize2g中的最大堆值在镜像内通过 IsolateArgumentParser.java 写入隔离堆参数供运行期堆管理器参见 DynamicHeapSizeManager.java读取。Build Options完整选项表解读运行native-image --print-options即可生成如下表格与文档自动同步生成。这里给出完整清单并补充默认值与使用方式说明。CommandTypeDescriptionDefaultUsage--add-exportsStringvaluemodule/packagetarget-module(,target-module)*更新module使其向target-module导出package无论模块声明如何。target-module可为ALL-UNNAMED以导出给所有未命名模块None--add-exportsadd-exports--add-opensStringvaluemodule/packagetarget-module(,target-module)*更新module使其向target-module打开package无论模块声明如何None--add-opensadd-opens--add-readsStringvaluemoduletarget-module(,target-module)*更新module使其读取target-module无论模块声明如何。target-module可为ALL-UNNAMEDNone--add-readsadd-reads--colorString构建输出颜色always、never或autoNone--colorcolor--emitString构建后额外输出数据。使用build-report输出详细构建报告例如--emit build-report或--emit build-report/tmp/report.htmlNone--emitemit--enable-all-security-servicesString将全部安全服务类加入生成的镜像None--enable-all-security-servicesenable-all-security-services--enable-monitoringString启用运行期可检视 VM 的监控特性。逗号分隔列表可含heapdump、jfr、jvmstat、jmxserver实验性、jmxclient实验性、threaddump、nmt实验性、jcmd实验性或all已弃用行为不带参数时默认即all。例如--enable-monitoringheapdump,jfrdeprecated-default--enable-monitoringenable-monitoring--enable-native-accessString允许执行受限原生操作的模块逗号分隔列表模块名可为ALL-UNNAMEDNone--enable-native-accessenable-native-access--enable-sbomString基于静态分析结果为可执行文件或共享库生成软件物料清单SBOM。逗号分隔列表可含embed将 SBOM 存入二进制数据段、export保存到输出目录、classpath以 Java 资源形式置于 classpath 的META-INF/native-image/sbom.json、hashes包含组件哈希、strict若任何类型无法匹配 SBOM 组件或组件哈希创建失败则中止构建、cyclonedx当前唯一支持的格式、class-level包含类级元数据。默认嵌入 SBOM用--enable-sbomfalse关闭embed--enable-sbom--enable-sbom--exact-reachability-metadataString为反射、资源、JNI 与序列化启用精确且友好的处理空--exact-reachability-metadataexact-reachability-metadata--exact-reachability-metadata-pathString对给定 class-path/module-path 条目中的所有类型触发精确的反射、资源、JNI 与序列化处理None--exact-reachability-metadata-pathexact-reachability-metadata-path--featuresString逗号分隔的 Feature 实现类全限定名列表None--featuresfeatures--future-defaultsString启用计划在未来版本成为默认值的选项。逗号分隔列表可含all、none、run-time-initialize-jdk、class-for-name-respects-class-loader、run-time-initialize-file-system-providers、run-time-initialize-security-providers、run-time-initialize-resource-bundles、explicit-feature-singleton-registration。推荐使用--future-defaultsalldefault-value--future-defaultsfuture-defaults--initialize-at-build-timeString逗号分隔的包与类列表并隐式包含其全部超类这些类型在镜像生成期间初始化。空字符串表示所有包空--initialize-at-build-timeinitialize-at-build-time--initialize-at-run-timeString逗号分隔的包与类列表并隐式包含其全部子类这些类型必须在运行期初始化而非镜像构建期。当前不支持空字符串空--initialize-at-run-timeinitialize-at-run-time--libcString选择 libc 实现。可用实现glibc、musl、bionicNone--libclibc--link-at-build-timeString要求类型在镜像构建期被完整定义。不带参数时选项作用域内的所有类都必须被完整定义空--link-at-build-timelink-at-build-time--link-at-build-time-pathsString要求给定 class/module-path 条目中的所有类型在镜像构建期被完整定义None--link-at-build-time-pathslink-at-build-time-paths--list-cpu-featuresString显示目标平台特定的 CPU 特性并退出None--list-cpu-featureslist-cpu-features--list-modulesString列出可观察模块并退出None--list-moduleslist-modules--native-compiler-optionsString提供用于查询代码编译的自定义 C 编译器选项None--native-compiler-optionsnative-compiler-options--native-compiler-pathString提供用于查询代码编译与链接的 C 编译器自定义路径None--native-compiler-pathnative-compiler-path--native-image-infoString显示原生工具链信息与镜像构建设置None--native-image-infonative-image-info--parallelismString构建进程允许使用的最大线程数None--parallelismparallelism--pgoString逗号分隔的文件列表从中读取用于 AOT 编译代码的 profile-guided optimizationPGO数据未指定时读取default.iprof。每个文件须包含单个 PGOProfiles 对象以 JSON 序列化可用 gzip 压缩default.iprof--pgopgo--pgo-instrumentString对 AOT 编译代码插桩以收集 PGO 数据到default.iprofNone--pgo-instrumentpgo-instrument--pgo-samplingString通过对 AOT 编译代码采样来收集 PGO 优化数据None--pgo-samplingpgo-sampling--sharedString构建共享库None--sharedshared--silentString静默构建输出None--silentsilent--staticString构建静态链接可执行文件需要静态 libc 与 zlibNone--staticstatic--static-nolibcString构建静态链接可执行文件但 libc 动态链接None--static-nolibcstatic-nolibc--targetString选择 native-image 编译目标格式OS-architecture。默认为主机 OS-架构组合None--targettarget--trace-object-instantiationString逗号分隔的类全限定名列表跟踪这些类的对象实例化None--trace-object-instantiationtrace-object-instantiation-OString控制代码优化级别b- 最快构建时间s- 优化体积0- 不优化1- 基础优化2- 高级优化3- 全部优化以获得最佳性能None-O-O-WerrorString将警告视为错误并终止构建all-Werror-Werror-daString即-da[:[packagename]...\|:classname]或-disableassertions[:...]。以指定粒度在运行期禁用断言空-da-da-dsaString即-disablesystemassertions。在运行期禁用所有系统类的断言None-dsa-dsa-eaString即-ea[:[packagename]...\|:classname]或-enableassertions[:...]。以指定粒度在运行期启用断言空-ea-ea-esaString即-enablesystemassertions。在运行期启用所有系统类的断言None-esa-esa-gString生成调试信息2-g-g-marchString为特定机器类型生成指令。AMD64 默认x86-64-v3AArch64 默认armv8.1-a。用-marchcompatibility获得最佳兼容性用-marchnative在同机或同 CPU 特性机器上部署时获得最佳性能。用-marchlist列出所有可用机器类型None-march-march-oString生成的输出文件名None-o-o--gcEnum选择 native-image 垃圾收集器实现。允许值epsilon、serial、G1serial--gcvalue--add-modulesString除初始模块外要解析的根模块。模块名可为ALL-DEFAULT、ALL-SYSTEM、ALL-MODULE-PATH空--add-modules module name[,module name...]--bundle-applyString使用原始参数与文件从给定 bundle 文件构建镜像。若--bundle-apply后再传--bundle-create则用已应用参数加附加参数写出新 bundle空--bundle-applysome-bundle.nib[,dry-run][,container[container-tool][,dockerfileDockerfile]]--bundle-createString除镜像构建外创建允许日后重建该镜像的 Native Image bundle 文件*.nib。若传入 bundle 文件名则以此命名否则由镜像名派生。bundle 选项可扩展,dry-run与,containerdockerfileDockerfile使用用户提供的 Dockerfile空--bundle-create[new-bundle.nib][,dry-run][,container[container-tool][,dockerfileDockerfile]]--class-pathPath用于搜索类文件的目录、JAR 与 ZIP 归档的冒号分隔列表空--class-path class search path of directories and zip/jar files--configurations-pathPath视为选项配置目录的目录冒号分隔列表空--configurations-path search path of option-configuration directories--debug-attachString镜像构建期间附加调试器默认端口 8000空--debug-attach[port or host:port (* 可用作 host 表示绑定所有接口)]--diagnostics-modeBoolean将镜像构建信息日志记录到诊断文件夹空--diagnostics-mode--dry-runBoolean输出将用于构建的命令行而不实际构建空--dry-run--enable-previewBoolean允许类依赖本版本的预览特性空--enable-preview--exclude-configString为“classpath/modulepath 模式 资源模式”的空格分隔对排除配置。例如--exclude-config foo.jar META-INF\/native-image\/.*.properties忽略所有名为foo.jar的 JAR 中META-INF/native-image下的全部.properties文件空--exclude-config--expert-optionsBoolean列出面向专家的镜像构建选项空--expert-options--expert-options-allBoolean列出面向专家的全部镜像构建选项自担风险使用。标记[Extra help available]的选项可用--expert-options-detail显示帮助空--expert-options-all--expert-options-detailString显示逗号分隔选项名的全部可用帮助。传*显示所有含额外帮助的选项空--expert-options-detail--helpBoolean打印本帮助信息空--help--help-extraBoolean打印非标准选项帮助空--help-extra--module-pathPath目录的冒号分隔列表每个目录是一组模块空--module-path module path...--print-optionsString打印完整选项表。可用格式table默认、markdown/md、json。消除了与手工文档表的重复空--print-options[format]--verboseBoolean启用详细输出空--verbose--versionBoolean打印产品版本并退出空--version-DString仅为镜像构建期设置系统属性空-Dnamevalue-EString允许 native-image 在镜像构建期间访问给定环境变量。省略env-var-value时取调用 native-image 的环境中的值空-Eenv-var-key[env-var-value]-JString将flag直接传给运行镜像生成器的 JVM空-Jflag-VString为native-image.properties文件中的占位符提供值空-Vkeyvalue-classpathPath目录与 zip/jar 文件的类搜索路径空-classpath class search path of directories and zip/jar files-cpPath类搜索路径同-classpath空-cp class search path of directories and zip/jar files-pPath模块路径空-p module pathargumentString一个或多个包含选项的参数文件空argument files值得注意的选项细节--enable-http、--enable-https、--enable-url-protocols已弃用应改用 reachability metadata可达性元数据因此不会出现在上述自动生成的表格中。其底层选项仍保留在源码中见 SubstrateOptions.java 的EnableURLProtocols定义具体迁移指引见 URL Protocols in Native Image。-O优化级别是日常构建最常用的开关之一追求快速迭代用-O b追求最小体积用-O s可配合-H:Preserve的大镜像场景生产部署追求性能用-O 3与 PGO 结合效果更佳。-J透传 JVM 参数-J-Xmx16g可增大构建期堆这与后文“内存需求”一节直接相关。--gc选择 GC默认serialG1适合大堆低延迟场景epsilon为无回收模式适合对内存占用极敏感且对象生命周期可控的场景。常用进阶选项除上述标准 Build Options 外还有一批专家级选项在日常排障与优化中非常有用例如导出native-image构建器的图、打印构建期统计等。本节挑选其中最实用的几类展开。构建输出与 Build ReportNative Image 提供信息丰富的构建输出包含构建过程中的多项统计指标。如需机器可读的构建输出可用-H:BuildOutputJSONFile选项请求 JSON 格式输出之后交由监控工具处理该 JSON 文件遵循build-output-schema-v0.9.4.json中定义的 JSON schema 进行校验。若需要更全面的报告可使用--emit build-report选项生成详尽的 Build Report也可指定输出路径如--emit build-report/tmp/report.html。注意--emit build-report选项在 GraalVM Community Edition 中不可用。Graph Dumping转储编译器图Native Image 复用了 GraalVM 调试环境中的图转储、日志、计数器等选项。这些 GraalVM 选项既可以作为hosted options转储native-image构建器的图也可以作为runtime options在运行期动态编译时转储图。可正常工作的 Graal 编译器选项包括Dump、DumpOnError、Log、MethodFilter以及用于指定 dump 处理器文件名与端口的选项。典型用法-H:Dump -H:MethodFilterClassName.MethodName转储native-image构建器的编译器图-XX:Dump -XX:MethodFilterClassName.MethodName在运行期转储编译图。前者面向构建期分析例如排查 AOT 编译时的优化缺失后者面向运行期动态编译例如 Truffle 语言运行时的图查看。保留包、模块或类-H:PreserveGraalVM 25 引入了-H:Preserve选项。它可以指示native-image工具将整个包、模块或 classpath 上的全部类保留在原生可执行文件中——即使静态分析无法发现它们。-H:Preserve支持以下用法-H:Preserveall保留整个 JDK 与 classpath 的全部元素。这会生成更大的镜像但确保所有代码都被包含有助于解决缺失元数据的问题。-H:Preservemodulemodule保留给定模块的全部元素。-H:PreservemoduleALL-UNNAMED保留 classpath由-cp提供上的全部元素。-H:Preservepackagepackage保留给定包的全部元素。可用*包含所有子包例如-H:Preservepackagecom.my.pkg.*,packagecom.another.pkg.*。注意仅支持*通配符其他正则模式不允许。-H:Preservepathcp-entry保留给定 class-path 条目的全部元素。上述用法可逗号组合-H:Preservepathcp-entry,modulemodule,modulemodule2,packagepackage。保留行为还有几个重要细节当为某个被保留的捕获类capturing class生成的 lambda 代理类被触及时Native Image 会一并保留该 lambda 代理类并像其他被保留类一样为其注册反射与 JNI 访问可序列化 lambda 也会注册到 Java 序列化中。多接口代理类、3 维及以上数组、以及作为资源的.class文件仍需在原生镜像中显式配置。工具类相关的 Java 模块默认不随-H:Preserveall包含需要时须用-H:Preservemodulemodule显式添加。若遇到与--initialize-at-build-time相关的报错请遵循错误信息中的建议处理。注意使用-H:Preserveall需要大量内存且生成的镜像会显著变大。可使用-Os标志减小镜像体积详见 优化与性能。源码视角-H:Preserve 的实现-H:Preserve的底层实现在 PreserveOptionsSupport.java 中常量PRESERVE_ALL all与PRESERVE_NONE none定义了顶层选择器parsePreserveOption负责解析选项值拆分为逗号分隔的片段后按all/none/ 扩展选择器三种分支处理其中all分支通过classLoaderSupport.setPreserveAll(...)生效none分支清空全部选择器选项被限定只能从命令行使用来自配置文件等其他来源会被UserError.abort拒绝进入 preserve 模式后构建器会强制开启UseConservativeUnsafeAccess若用户未显式设置否则报错以加速分析JDK_MODULES_TO_PRESERVE常量定义了-H:Preserveall时默认纳入的 JDK 模块白名单含java.base、java.desktop、java.xml、java.sql、java.logging、java.naming、java.management等约 30 个模块并刻意排除了jdk.localedata会带入约 250 MB 代码、内部模块、工具类模块如java.compiler及当前 Native Image 尚不支持的模块。选项本身的声明位于 SubstrateOptions.javaPreserve为HostedOptionKeyAccumulatingLocatableMultiOptionValue.Strings可叠加多次并配套提供IgnorePreserveForClassesDebug 级忽略-H:Preserve引入的某些类/包用于规避 preserve 引发的问题与PreserveIncludesJNI默认 true控制保留是否包含 JNI 注册两个辅助选项。与元数据追踪联用-H:Preserve还可以与从原生镜像进行元数据追踪dynamic metadata collection from a native image联用从一次有代表性的运行中收集可达性元数据native-image -H:UnlockExperimentalVMOptions -H:MetadataTracingSupport -H:-UnlockExperimentalVMOptions -H:Preservepackagecom.example.library.* ... ./application -XX:TraceMetadatapathmetadata-output -XX:TraceMetadataConditionPackagescom.example.application第一条命令构建一个启用了元数据追踪支持并按包保留的镜像第二条命令运行该应用将运行期触达的类型/方法/字段等追踪结果写入metadata-output随后可回填为 reachability metadata 配置。内存需求Native Image 编译对内存需求较高尤其在建大型项目、使用-H:Preserveall或--pgo-instrument时。若遇到OutOfMemoryError: Java heap space可按以下顺序处理使用-Os标志减小镜像体积详见优化与性能改用更精确的保留粒度如-H:Preservepackagepackage替代-H:Preserveall用-J-Xmxng增加堆内存——n视机器可用内存与构建需求而定例如-J-Xmx16g。系统属性构建期与运行期的边界可以使用-Dsystem.propertyvalue语法在镜像构建期定义系统属性。该选项为native-image工具设置系统属性但该属性不会包含在生成的可执行文件中。不过JDK 系统属性会包含在生成的可执行文件中并在运行期可见。举例说明-Dsystem.propertyvalue仅在构建期可见。若原生可执行文件访问该属性将得到null-Djava.version25在构建期与原生可执行文件中均可见因为该值默认被复制进二进制文件。以下系统属性会被自动复制进生成的可执行文件NameDescriptionfile.separator文件分隔符file.encoding默认 locale 的字符编码java.versionJava 运行时环境版本java.version.date版本的 GA通用可用日期java.class.versionJava 类格式版本号java.runtime.versionJava 运行时环境版本java.specification.nameJava 运行时环境规范名称java.specification.vendorJava 运行时环境规范厂商java.specification.versionJava 虚拟机规范版本java.vm.specification.nameJava 虚拟机规范名称java.vm.specification.vendorJava 虚拟机规范厂商java.vm.specification.versionJava 虚拟机规范版本line.separator行分隔符native.encoding指定宿主环境的字符编码org.graalvm.nativeimage.kind指定镜像构建为共享库还是可执行文件path.separator路径分隔符stdin.encoding指定System.in的编码stdout.encoding指定System.out与System.err的编码sun.jnu.encoding指定解析命令行传入值时的编码这套“构建期系统属性不落地、JDK 系统属性自动复制”的行为恰好体现了 Native Image 封闭世界假设closed-world assumption的一个侧面应用自定义的-D属性若需在运行期读取应通过-D与显式配置如-R:运行时选项或 reachability metadata 中的系统属性配置配合实现。小结本文以native-image构建器选项为核心系统梳理了以下要点选项查询入口--help/--help-extra/--expert-options/--print-options[table|md|json]四类命令覆盖从标准到专家的全部选项双前缀语义-H:hosted 选项配置构建并设定运行期默认值常量折叠进镜像-R:runtime 选项在构建时设定运行期初始值运行期默认前缀为-XX:完整选项表涵盖链接/模块处理、监控与 SBOM、类初始化策略、PGO、静态/共享链接、GC 选择、优化级别、断言、bundle 重建、参数文件等全部 Build Options实用进阶技巧JSON 构建输出与 Build Report、-H:Dump/-XX:Dump图转储、GraalVM 25 的-H:Preserve保留机制及其内存调优建议系统属性边界构建期-D不随镜像分发而 JDK 系统属性自动复制进二进制。相关文档Build Configuration参数求值顺序Build OverviewBuild OutputOptimizations and PerformanceAutomatic Metadata CollectionURL Protocols in Native Image【免费下载链接】graalGraalVM compiles applications into native executables that start instantly, scale fast, and use fewer compute resources 项目地址: https://gitcode.com/gh_mirrors/gr/graal创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考