Java11被宣布为最新的LTS版本.因此,我们正在try 基于这个Java版本启动新的服务.

但是,Java 11的基本Docker映像比Java 8的等效映像大得多:

(我只考虑每个Java版本的official OpenJDKthe most lightweight个图像.)

深入挖掘发现了以下"东西":

  • openjdk:11-jre-slim图像使用基本图像debian:sid-slim.这带来了两个问题:

    • 这是大于alpine:3.8的60 MB

    • Debian sid个版本不稳定

  • 图中安装的openjdk-11-jre-headless包比openjdk8-jre包大3 times larger(在运行的Docker容器内):

    • openjdk:8-jre-alpine:

      / # du -hs /usr/lib/jvm/java-1.8-openjdk/jre/lib/
      57.5M   /usr/lib/jvm/java-1.8-openjdk/jre/lib/
      
    • openjdk:11-jre-slim:

      # du -sh /usr/lib/jvm/java-11-openjdk-amd64/lib/
      179M    /usr/lib/jvm/java-11-openjdk-amd64/lib/
      

      深入研究之后,我发现了这种沉重感的"根源"——它是JDK的modules文件:

      # ls -lhG /usr/lib/jvm/java-11-openjdk-amd64/lib/modules
      135M    /usr/lib/jvm/java-11-openjdk-amd64/lib/modules
      

所以,现在问题来了:

  • 为什么alpine不再用作Java11瘦图像的基础图像?

  • 为什么不稳定的sid版本用于LTS Java映像?

  • 为什么OpenJDK 11的slim/headless/JRE包与类似的OpenJDK 8包相比如此之大?

    • 在OpenJDK 11中,这modules个文件带来135MB的空间是什么?

作为这些挑战的解决方案,我们可以用这个答案:Java 11 application as docker image

推荐答案

为什么alpine不再用作Java11瘦图像的基础图像?

这是因为,遗憾的是,目前没有针对Alpine的官方稳定OpenJDK 11构建.

Alpine使用MUSL libc,而不是大多数Linux使用的标准glibc,这意味着JVM必须与MUSL libc兼容才能支持普通的Alpine.MUSL OpenJDK移植是在OpenJDK的Portola项目下开发的.

当前状态总结在OpenJDK 11 page页上:

本页之前提供的Alpine Linux版本从JDK 11 GA起被删除.它还没有准备好生产,因为它还没有经过充分测试,不能被视为GA版本.请使用早期访问JDK 12 Alpine Linux版本.

Alpine目前唯一稳定的OpenJDK版本是由IcedTea项目提供的7和8.

然而,如果你愿意考虑除了官方OpenJDK之外,Azul's Zulu OpenJDK提供一个令人信服的替代方案:

  • 它支持Java 11 on Alpine musl(截至本文 compose 时的11.0.2版);
  • 它是一个经过认证的OpenJDK构建,使用OpenJDK TCK compliance suite进行验证;
  • 它是免费的,开源的,docker ready(Dockerhub).

有关支持可用性和路由图,请参阅Azul support roadmap.

Update, 3/6/19:截至昨天,阿尔卑斯山存储库中有openjdk11个可用!可以在阿尔卑斯山上用以下方法抓取:

apk --no-cache add openjdk11

该软件包基于Portola项目的jdk11u个OpenJDK分支和ported修复程序,下面是PR个.感谢阿尔卑斯山队.

为什么要将不稳定的sid版本用于LTS Java镜像?

That's a fair question / request. There's actually an open ticket for providing Java 11 on a stable Debian release:
https://github.com/docker-library/openjdk/issues/237

Update, 26/12/18:问题已经解决,现在OpenJDK 11 slim映像基于最近发布的stretch-backports OpenJDK 11(PR link).

为什么OpenJDK 11的slim/headless/JRE包与类似的OpenJDK 8包相比如此之大?在OpenJDK 11中,这modules个文件带来135MB的空间是什么?

Java 9 introduced the module system, which is a new and improved approach for grouping packages and resources, compared to jar files. This article from Oracle gives a very detailed introduction to this feature:
https://www.oracle.com/corporate/features/understanding-java-9-modules.html

modules文件Bundle 了JRE附带的所有模块.完整的模块列表可以用java --list-modules打印.modules确实是一个非常大的文件,正如 comments 所说,它包含所有标准模块,因此相当臃肿.

然而,需要注意的一点是,它取代了rt.jartools.jar,这两个版本已经弃用,因此,与9版本之前的OpenJDK版本相比,考虑到modules的大小时,应该减go rt.jartools.jar的大小(它们加起来应该占80MB左右).

Java相关问答推荐

有没有方法可以修复错误错误:无法初始化主类code_editor?

Java字符串常数池困惑

从技术上讲,OPC UA客户端是否可以通过转发代理将请求通过 tunel 发送到OPC UA服务器?

有没有一种方法使保持活动设置专用于java.net.http.HttpClient的一个实例

现场观看Android Studio中的变化

Java编译器抛出可能未正确初始化的错误?

安装Java Jar应用程序的Install4j遇到ClassNotFoundException的运行时错误

GSON期间的Java类型擦除

将响应转换为带值的键

如何仅使用键/ID的一部分(组合)高效地返回映射值?

基于配置switch 的@Controller的条件摄取

Spring动态反序列化JSON可以是列表,也可以只是一个对象

对从Spring Boot 3.1.5升级到3.2.0的方法的查询验证失败

为什么相同的数据条码在视觉上看起来不同?

Maven-Dependency-Plugin 3.6.+开始查找在依赖关系:分析目标期间找到的新的使用的未声明依赖关系

如何在Java中的重写方法参数中强制(Enum)接口实现?

如何使用外部函数从Java中获取C++ struct 的返回值&;内存API

如何通过gradle命令行从build.gradle获得Java targetCompatibility

当我将鼠标悬停在javafxTextArea上时,如何更改鼠标光标?

如何在 WebSphere Application Server 内的托管线程上运行 BatchEE 作业(job)?