【发布时间】:2020-01-22 13:01:25
【问题描述】:
我正在尝试为纤薄的 Docker 映像提供最小的 JRE。使用 Ubuntu 上的 open-jdk-11 附带的 jlink 11.0.4,使用此自定义 JRE 构建的映像实际上大于使用默认 JRE 构建的映像。我认为这是由于 cutom_jre/lib/server/libjvm.so 的大小非常大
我正在关注来自 Arun Gupta 的 Kubernetes for Java Developers on Linkedin Learning。在某些时候,我注意到我的 Ubuntu 实例上有一个奇怪的行为。除了这门课程,我还需要为一个最小的 Spring Boot 应用程序提供一个自定义 JRE,以便将它用于一个纤薄的 Docker 映像。
jlink \
--output myjre \
--add-modules $(jdeps --print-module-deps target/greeting.jar),\
java.xml,jdk.unsupported,java.sql,java.naming,java.desktop,\
java.management,java.security.jgss,java.instrument \
这种方法在课程中运行良好,my_jre 的大小适合为应用程序构建最小的 Docker 映像。问题是在我的设置中我使用的是 openjdk-11,而不是 openjdk-9。
使用我的设置,my_jre 的结果大小会非常大(~380mb)。经过一番调查,我发现这主要是并且可能只是由于my_jre/lib/server/libjvm.so的大小。
在此尝试之前,我没有任何使用 jlink 的经验。经过一些试验和错误,并浏览了 github 上的类似问题,我找到了 jlink 功能之外的解决方法。
运行带有--strip-unneeded 标志的strip 实用程序将缩小libjvm.so 的大小,并有可能实现主要目标:为精简的Docker 映像提供最小的JRE(~113mb)。
strip -p --strip-unneeded myjre/lib/server/libjvm.so
我希望有知识的人能更深入地解释这种天赋的背景。就这种行为而言,从 jdk9 到 jdk11 还有什么变化?除了 jdk9+ 提供的工具(如 jlink)之外,是否有任何标准流程可以在不使用任何外部工具的情况下实现这一目标?
【问题讨论】:
-
我不知道您使用的是哪个 JDK 版本,但我认为问题在于打包的模块(.jmod 文件)具有调试符号。在配置 JDK 构建时,可以选择调试信息的去向。在 JDK 13 中,至少在 Linux 上,
jlink --strip-debug选项将从本机库中删除符号。在 JDK 13 之前,它只会从类文件中去除调试属性。所以是的,总结是包含本机调试符号的发行版的一个已知问题。 -
虽然我仍然需要弄清楚 strip 在低级别做什么,但我明白了。感谢您的评论。这是 jdk 13 中一个受欢迎的变化。我尚未在 Windows 或 Mac 上进行测试,但问题中的示例是在 Ubuntu 上运行的。今天我在ubuntu中依次做了两次测试,运行
jlink --strip-debug两次,一次用openjdk-11-jdk,一次用亚马逊Corretto。自定义 JRE 的输出是: - OpenJDK:340mb - OpenJDK Corretto:52mb
标签: java docker java-11 jlink openjdk-11