关于Unsafe的争论仍在继续–“总体Java 9感觉有些破烂”

JAXenter:有一个计划使JDK 9中的用户无法使用sun.misc.Unsafe 。这是什么原因?

Christoph Engelbert:首先,我猜没有人反对该计划。 该API太可怕了,它从来没有打算一开始就被使用过,但是它是可用的并且被使用了。 让我稍后再谈。

删除sun.misc.Unsafe的原因之一是使Java更加安全。 sun.misc.Unsafe提供了随机的内存峰值和戳数,而没有边界检查,并且内存访问已内联到JIT编译器的优化本机代码中。

彼得·劳瑞(Peter Lawrey):虽然API不是标准的,但之所以使用它是因为:

  • 在那里
  • 好玩
  • 比使用JNI更好
  • 真的没有别的选择

很长一段时间以来,设计师一直以为人们只是在使用它,是因为它在那里或很有趣,并且不明白为什么有人会需要它,除了他们自己,他们确实需要它,但是没有人可能会需要它。 我对此感到奇怪的是,设计师需要Unsafe来实现低级库,并且似乎假设没有其他人也需要编写低级库。

现在,他们意识到,在Java 9发行不久之前,他们不能仅仅消除Unsafe,因为它已在很多地方使用。 如此众多的库仅使用了很少的内部API。 但是请注意,tools.jar的删除相对较少,主要是因为有一个更好的替代品Compiler API,而且这种替代已经存在了一段时间。

Christoph:我想Unsafe是有史以来使用最广泛的内部API,不仅在Java生态系统中。 就像彼得已经说过的那样,许多事情将在Java 9中消失,但是sun.misc.Unsafe可能是最常用的,但不是唯一的。 例如,OpenJFX项目仍使用com.sun.javafx中的类,因为该代码尚未开源(还好吗?)。 这意味着OpenJFX也无法在Java 9上实现。

社区对此计划表现出一定的抵制。 为什么有这么多人看到有关删除sun.misc.Unsafe API的问题?

Christoph:如前所述,它可用并且使用很多。 有许多不同的用例和原因,例如序列化,性能,延迟,模拟框架,以及更多严重依赖于sun.misc.Unsafe的原因 。 如果首先不能使用Unsafe API,那么Java生态系统今天看起来可能会有所不同。

彼得:有两个问题。 库的用户不希望其应用程序损坏并且可能不准备升级。 他们希望迁移到Java 9尽可能顺利。 不必担心JVM的更改和更新库,当使用Java 9并没有太多好处的时候,这更有可能不会发生。 一旦更好地理解了所有风险,可能会有更多的人使用Java 10。

第二个问题是库的开发人员。 最初宣布不安全将要消失,但这错过了在大多数情况下仅使用不安全的论点,因为没有更好的选择。 后来有人建议在Java 9中提供一种替代方法,但是随着时间的流逝,似乎已经没有冻结Java 9功能集文件的所有功能的替代品了。

对于在许多机器上的生产中使用的代码,使用Unsafe是因为除了使用其他语言之外别无选择。 在某些情况下,您可能已经使用JNI并为一系列平台发布了DLL和SO。 与使用未记录但已广泛使用的类相比,使用JNI被视为具有更大的风险和更低的安全性。

但是,在许多情况下,JNI不能像Unsafe中的内在函数那样执行。 这意味着这些“本机”方法被一个或多个机器代码指令所代替。 也就是说,对于琐碎的操作,内在函数要比使用JNI快得多。

Christoph:由于C和Java之间的数据类型转换,JNI的开销很大,它一直是JNI的瓶颈。 另外,正如Peter所言,Unsafe操作具有很好的内在性,因此实际的C代码从未真正使用过,您只能直接进行本地内存访问。

您要求提供技术解决方案的建议书–这样的外观如何?

Christoph:我是Google Doc的最初创建者之一,开始了如此大的讨论。 作为Hazelcast的一部分,个人而言,我担心当sun.misc.Unsafe最终永久消失时,Java生态系统会发生什么。 现在,我们已经听说会有一个命令行参数可以“重新导出”隐藏的sun.misc程序包,但是它将保留多长时间? 到目前为止,没有很多替代方案,或者像VarHandles一样,它们似乎还不能完全解决问题。 上周,我们在JCrete考察了VarHandles,并为一些问题(例如快速数组访问)提供了解决方案,但他们仍然错过了许多本应解决的问题。 但是,我们与工程师合作,至少可以获得适用于Java 9的VarHandles。

彼得:克里斯多夫(Christoph)撰写的论文成功地引起了人们的关注。 我之前曾尝试过进行类似的讨论,但是没有运气。 我过去提出的建议是扩展ByteBuffer API或类似的扩展。 纪事报(Chronicle)和Aeron都这样做,在我们的案例中,我们有这样的替代品,已经在生产中使用了多年。 这仅涵盖了不安全操作的一部分,但似乎是解决我们必须解决的API局限性的一种更自然的方法,而不是发明一种全新的方法。 VarHandles的引入对于从根本上说是一条访问原始内存的单机指令来说,似乎是一个过于复杂的解决方案,我很期待看到它如何用于堆外数据结构。

Christoph:在这种情况下,我并不完全同意,特别是在实现方面,VarHandles看起来极其复杂,但是无论如何,大多数用户都不会这么做。 另一方面,我有点像VarHandles API,它移动了Buffers的不同实现,我们目前有一个数组支持的缓冲区,一个Unsafe的支持缓冲区,一个ByteBuffer的反向缓冲区,通过VarHandles移至单个轻量级包装实现,(如果正确实施)将统一对所有不同数据存储的访问。

您还提议了一个工作组。 您对该小组有什么期望?

Christoph:工作组即将组建,其想法是将Java社区内部目前传播的所有知识和参与结合起来。

彼得:我认为我们需要演示真实的用例,以便JVM设计人员可以找出解决它们的最佳方法。

您提到了VarHandles。 您能解释一下这个想法以及它如何解决一些问题吗?

Christoph:我们上周在JCrete开会,就删除Unsafe进行了热烈的讨论 。 由于讨论的缘故,我目前正在深入研究VarHandles原型,并执行第一个测试,以弄清它是否真的可以按承诺解决问题,以及速度是否能够保持稳定。 到目前为止,我发现了一些尚待处理的用例,并且正在与Paul Sandoz合作解决这些用例。 VarHandles看起来是替换API的第一步,但是它只会替换sun.misc.Unsafe的内存访问部分仍然缺少许多需要替换的功能。

彼得:我们的主要用例是堆外,共享的持久数据结构。 好处是我们可以像在线程之间共享数据一样快地在进程之间使用共享数据。 我们还可以以每秒三千万次更新的速度持续保存数据。 我们的一位客户在市场高峰期每秒写入2400万个市场数据事件。 由于代码是无GC的,因此无需暂停即可完成。 过去,这可能只能使用C ++或C来实现,但是Unsafe允许我们在需要的地方获得C的性能,但是它具有Java的可移植性和易于开发的特性。

Christoph:是的,Peter在这里,VarHandles还不能解决这个问题。 据我所知,巴拿马项目将是一个解决方案,但它不会在Java 10之前出现。总体而言,Java 9感觉有些破损,正如我在JCrete讨论中所说,我们可能要考虑:我们不跳过Java 9吗?

彼得:也许Java 9将进行我们必须进行的更改,以便我们可以继续使用JVM平台,但是从最终用户的角度来看,它似乎不像Java 8那样引人注目,并且我可以想象有很高的百分比的用户将跳过Java 9。

翻译自: https://jaxenter.com/debate-over-unsafe-continues-119208.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值