JEP 148: Small VM | 小型虚拟机
摘要
支持创建一个不超过 3MB 的小型虚拟机。
目标
进行必要的修改,以便我们可以选择性地构建一个不超过 3MB 的小型虚拟机。(作为参考,当前客户端和服务器 VM 分别约为 6MB 和 9MB。)
这将通过允许在构建时排除某些功能,并在可能的情况下优化 C++ 编译代码的空间来实现。小型 VM 的性能下降高达 5% 是可接受的。非小型构建的性能不得下降。
非目标
没有计划保留全部功能。没有计划在运行时使功能可选。
成功指标
libjvm.so
的大小小于 3MB,且性能下降不超过 5%。
动机
小型设备对静态和动态内存占用有非常严格的要求。为了使 Java 能够在此类设备上良好运行,我们需要减少 JRE 的总体静态和动态占用。
描述
在实现 Java Kernel 时,已经进行了减少 libjvm.so
大小的前期工作。内核 VM 移除了许多较大的组件,如额外的垃圾收集器、C2 JIT 和 JVMTI 的大部分。
内核 VM 没有得到维护,也从未在 Linux 上实现。本项目的第一步是恢复 Linux 上等效的 VM。
在内核 VM 中,修改了 makefile 和相关构建文件以排除对所需功能不必要的文件。我们采用了一种略有不同的方法,并计划使用条件语句修改源文件,而不是修改构建文件。现有的条件符号 KERNEL
将变为 MINIMAL_JVM
,内核 VM 排除的源文件将被 #ifndef MINIMAL_JVM
包围。此外,为了更精细地控制哪些内容包含在最小 VM 中,将定义如 INCLUDE_<something>
之类的符号来包含否则将被排除的功能。对于最小 VM,这些符号将不会被定义。
一旦最小 VM 在所需平台上稳定后,其他不必要的功能将变为可选。我们认为实现这一目标的主要方法是从小型 VM 中移除 JVMTI、java.lang.instrument
支持(在 sun.instrument
中实现)、sun.management
和监控(PerfDataManager
的一部分)。
JVMTI 的大部分已经从内核 VM 中移除。剩余的 JVMTI 代码将通过 #ifdef
进行构建时条件化。
如果未实现已删除功能的公共 API,则可能需要修改它们以在调用时抛出适当的异常。
本项目的另一部分包括找到可以在不牺牲性能的情况下优化空间的文件。这涉及修改构建过程,以便可以轻松指定哪些文件需要针对空间进行优化。我们将使用 gcc 选项 -Os
对大多数文件进行空间优化。某些平台可能还有其他减少空间的选项。如果性能损失显著,将使用分析来确定哪些文件可以使用 -O3
进行编译以加快速度。这可能涉及将函数移动到不同的文件中,以便仅对需要性能的函数进行此方式编译。
测试
如果底层实现代码缺失,API 必须表现适当。更改必须通过 Java SE 8 TCK。需要进行性能测试以衡量减少工作的影响。
风险和假设
我们可能不知道 VM 对已删除功能的依赖。
有可能(但不太可能)是没有足够的可选功能可以移除以达到我们的目标。
假设 JDK 8 不会显著增加 libjvm.so
的大小。
影响
其他 JDK 组件:某些工具可能依赖于缺失的代码。
兼容性:在最小二进制文件中将不支持 JVMTI。
性能 / 可扩展性:在构建此配置时,可能会测量到对性能的轻微影响。
文档:需要记录二进制文件中不支持的内容,以及如果用户或工具尝试访问缺失功能时会发生什么。
TCK:可能需要一些 TCK 更改来支持因删除功能而导致的 API 更改。
质量保证(QA):需要额外的测试以确保小型二进制文件能够正确工作。可能需要更新测试以考虑可选功能。
用户体验:用户可能期望在所有 VM 上都具有完整功能,但小型 VM 中将省略某些功能。