社区开始围绕移除 sun.misc.Unsafe 类展开讨论

  • Abraham Marín Pérez
  • 谢丽

2015 年 8 月 3 日

话题:Java语言 & 开发架构

社区已经开始围绕如何处理 sun.misc.Unsafe 类展开讨论。虽然该类是一个不受支持的专有 API 的一部分,但由于它提供了从底层访问内存管理的能力,所以被广泛应用于许多流行的工具中。考虑到Oracle 已经表明了在某个时间点移除该类的意愿,开发者们正在寻找可行的替代方案。

自 Java 6 发布以来,Java 编译器就作了修改,当使用的类是专有 API 的一部分时,它就会警告开发者。专有 API 的类并没有在 OpenJDK 中定义,就是说,这些类可以随时修改或删除,而不需要任何事先警告;而且,由于Java TCK并没有涵盖它们,所以无法保证 JVM 所有不同的实现都会提供这些类,或者是即使提供了,也无法保证它们采用同样的处理方式。换句话说,通常根本就不鼓励开发人员使用这些类:

Application.java:37: 警告:Unsafe 是一个内部专有 API,可能会从未来的版本中移除

sun.misc.Unsafe 的问题在于,它提供了许多任何 OpenJDK 标准类都没有提供的功能,致使库作者不顾警告使用该类,因为他们想要实现诸如原子内存操作、与本地代码快速交互或堆外内存访问(这里仅举几例)这样的功能。Spring、Mockito 和 java.util.concurrent 库是一些使用了 Unsafe 的工具实例,因此,它们会受到这一变化的影响。推而广之,任何使用了其中任意一种工具或库的 Java 应用程序(绝大多数应用程序)都会间接地受到影响。

在本文写作的时候,当前的讨论仍在进行当中,其中包括长期和短期替代方案。

从长期来看,Variable Handles会作为 sun.misc.Unsafe 的一个受支持的替代方案,取代 Unsafe 在对象字段和数组元素上的操作。就是说,虽然 Variable Handles 不是一个完全的 Unsafe 替代方案,但在某些场景下也已经够用。目前,Variable Handles 正按照 JEP 193 进行开发,目标是在 Java 9 中推出,但对于能否在 Java 9 特性完成的最后期限(2015 年 11 月)到来时提供一个完全的 Unsafe 替代方案,社区成员表示担忧。即使按时实现了完全的替换,在 Java 下一个版本发布之前,库作者也无法将他们的应用程序从 Unsafe 移植到到 VarHandles(除非他们开始针对 Java 9 开发版开展移植工作,这不是每个人都愿意做的),这就是为什么需要一个短期的解决方案。

就短期而言,Oracle 的计划是不删除 Unsafe,而是通过 Java 9 提供的新模块系统将其隐藏;虽然具体的实现机制尚未讨论,但该类将仍然可以使用。例如,当前的其中一个建议是,在启动 Java 应用程序的命令行中传递一个特定的标识以启用专有 API,其中包括 Unsafe;对于提供启动脚本的工具而言,这行得通,因为可以更新脚本,增加该标识,而终端用户仍然不知道这种变化,但对于那些由开发者使用的工具,由于他们自己启动应用程序,所以那很可能不能成为一种解决方案。

提案的潜在影响和围绕可能的解决方案的不确定性已经在社区引发了激烈的争论。不过,对于这种根本性变化,这是一种正常的反应,例如,在Oracle 提议将 G1 作为默认的垃圾收集器时就出现过类似的争论;在那种情况下,Oracle 接受了一个折中方法,增加了一个后备计划,如果 G1 的性能无法令人满意,就还原修改。

查看英文原文:The community initiates discussion to work around the removal of sun.misc.Unsafe

Java语言 & 开发架构