为什么JVM不能替代WebAssembly?

66
据我所了解,由于JavaScript具有动态性质,所以无法事先进行编译。因此,在运行时进行解释和即时编译会影响JavaScript的性能。这就是为什么要使用WebAssembly的原因。语言可以被提前编译成中间格式(WASM)。这样做可以提供良好的性能,因为运行时开销较小。
我的问题是,为什么不能使用JVM代替WebAssembly VM。Java被编译成中间格式(字节码)。将这些字节码提供给浏览器,然后JVM执行它们。JVM还支持JIT,可以实现接近本地代码的性能。
那么新的WebAssembly有什么必要呢?为什么不能将JVM集成到浏览器中,通过利用最流行的Java语言来实现高性能呢?

10
JVM可以被整合到Web浏览器中,这在技术上并没有不可能。然而,在JVM中运行的字节码始终比本地机器编译的代码慢,我认为主要原因可能是政治因素(不希望在应该保持中立/自由的Web中放置大量Java/Oracle)。不管怎样,这是一个有趣的问题 :) - sjahan
2
似乎WASM的性能并不是很好(原生),所以我倾向于真正考虑政治问题 :) - sjahan
6
时间会到来,Java 也将编译为 WASM。 - jayarjo
1
网络应该是开放的。Oracle是迄今为止最不开放的技术公司。 - Pacerier
JavaScript在与图像/视频处理相关的某些任务上比WASM快得多。您可以在此处自行查看:https://takahirox.github.io/WebAssembly-benchmark/ - Tobias Bergkvist
显示剩余3条评论
4个回答

78

有很多原因使得JVM不能替代WebAssembly作为runtime...

  • WebAssembly的设计考虑到了在http和基于浏览器的情况下使用,因此支持流式编译 - 即您可以在下载代码的同时开始编译。
  • 与Java/JVM语言相比,WebAssembly的验证规则非常简单,这支持快速编译,在网页加载时可以得到快速加载的结果。
  • WebAssembly的设计考虑到了“主机”环境的概念,即浏览器。
  • WebAssembly被设计成安全和简单,最小化整体攻击面。
  • WebAssembly被设计为支持许多语言(C、C++、Rust等),而JVM最初只为一种语言Java设计。

总的来说,WebAssembly的设计是为了在网络上支持多种语言。JVM的设计是为了在桌面上支持Java。这并不意味着一个比另一个更好,这是相对的。

最后,JVM已经与浏览器集成(Java Applets),但最终没有成功!


1
嗯,在某种程度上,人们已经考虑到了这个问题,并且a)创建了一个功能请求,要求GraalVM运行WebAssembly代码,b)或许有人会“简单地”在WebAssembly中实现JVM。 - Stefan Rother-Stübs
11
最终,JVM被整合到浏览器中(Java小程序),但是结果不尽如人意!作为一名Java爱好者,我认为JVM是通过插件使用的,但这并不等于它已经“与浏览器整合”。它是一个独立运行时,并有自己的更新方法等特点,这也是其失败的原因之一。他们应该创建一个轻量级/安全的虚拟机,可以与浏览器集成,而不是依靠70 MB的下载,同时CORBA发生变化时还需要进行安全修复。我非常赞同帖子中的其他观点! - Maarten Bodewes
@MaartenBodewes 这可以通过WASM和SubstrateVM完成吗? - Jayadevan Vijayan
这是所有重要设计决策的精彩总结,使wasm更适合成为浏览器的新VM。做得好! - Adam Sandor
2
我发现这些论点中大部分都是模糊的: 1)Java/Oak被设计用于在网络上传递代码。这就是为什么它有类加载器。"分布式代理"的整个概念早在Java被命名为Java之前就存在了。 2)Java和JVM字节码被设计用于快速编译和较低的内存使用。每个类文件可以独立编译,没有编译单元等概念。 3)JVM是以主机环境和适当的安全嵌入的概念来设计的。这就是JVM中"VM"的含义所在。 4)从计算规格的角度来看,我认为JVM甚至比WASM更简单。 - Talijanac
显示剩余5条评论

6
来自WebAssembly的高级目标之一:最小可行产品(MVP),其具有与asm.js大致相同的功能,主要针对C/C++;因此,他们最初的目标是在Web浏览器中运行C/C++程序,而不是运行Java代码。

4
Webassembly的主要好处与JVM的好处完全不同。JVM在更高的抽象层级上工作,进行垃圾回收并施加许多其他特定的做事方式,而且是针对一种特定语言的强烈指向,即使它可以托管其他语言。
另一方面,Webassembly在更低的抽象层级上工作,几乎不改变应用程序,并且可以看作是另一个编译目标。然而,与像编译到C或LLVM之类的东西相比,它的杀手级应用程序(Killer App)——通过灵活的编译目标实现可移植性,以及JVM也缺少的地方——是它具有内置的安全模型。它天生就是为需要运行不可信代码的平台设计的,并且是第一个真正流行起来的这样的编译目标。
由于所有新编写的代码的很大部分现在都在云端或浏览器中运行,并且本质上是不可信的,这对于采用率来说真的非常重要。编译代码本身具有限制意味着您可以在同一进程中安全地运行来自不同用户的许多未经信任的WASM编译片段,并编写像无服务器REST端点之类的东西。
这也意味着您可以探索新的并发模型,例如Lunatic,它提供了多语言 Erlang 进程般的语义,其中任何语言编写的同步代码都可以被沙盒化为轻量级进程并由抢占式调度程序运行。这是可能的,因为Wasm天然就对沙盒友好,所以您可以得到强有力的保证,确保任何一段 wasm 代码允许做什么。

0

JVM 可以运行以下语言:

  • JavaScript
  • Python(Jython)
  • Ruby(JRuby)
  • Groovy
  • Scala
  • C++(使用 JNI)

不幸的是,由于 Sun(Java 的前维护者)无法提供足够的支持,浏览器中对 Java 的支持已被删除。

就像 Flash 最终失去了一样。


JVM能否在浏览器上运行JNI而不使用WASM? - SOFe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接