@lsmn
2015-08-03T09:41:42.000000Z
字数 1554
阅读 2611
Java
Unsafe
Oracle
JDK
社区已经开始围绕如何处理sun.misc.Unsafe类展开讨论。虽然该类是一个不受支持的专有API的一部分,但由于它提供了从底层访问内存管理的能力,所以被广泛应用于许多流行的工具中。考虑到Oracle已经表明了在某个时间点移除该类的意愿,开发者们正在寻找可行的替代方案。
社区已经开始围绕如何处理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的性能无法令人满意,就还原修改。