返回 登录
0

JVM并不是那么重量级

原文:The JVM is not that heavy
作者:Kenneth Kalmer
翻译:Vincent

译者注:很多人误认为JVM是一个很重量级的框架,本文作者之前也是这么认为的,但是在这篇文章中,作者从几个层面分析了一下,可以看出JVM并不是我们想象中的那么“重”。以下为译文。

大多数情况下,我之所以反对Clojure,就是由于JVM。因为它实在是太重量级了。

这是几周前在ZA Tech科技公司的Slack团队中出现的声音。假期的时候观看了一些关于Clojure的讨论后发现演讲者们又一次又一次地提到了这个反对意见。

关于这一点,我在Slack中做过一段说明。现在,我为了更广泛的讨论而把它记录下来。

背景

我以前也认为JVM是非常重量级的。这是在2000年初,我把它和PHP进行比较以后得出的结论。还有其它一些像.NET和ColdFusion重量级的选择。有一些较轻量级的替代方案,比如Perl和Python,但是我当时在Windows上,所以ActivePerl和ActivePython也有点重。

当我在Heroku上部署了一个小的生产应用时,我第一次克服了对JVM的“恐惧”。这款应用每天只需要完成一项任务。它生成了一堆的PDF文件,然后将它们上传到iSign (现在已经不存在了)用于存储和共享。iSign本身就是一个经典的Rails应用,它托管在3个AMI上。这个运行在JVM上的小小的应用(除了-server -Xmx=512M)生成PDF文件如此之快,以至于在每次运行时基本上都杀死了3个节点集群。

尽管我还是觉得用起来有点重,但我爱上了JVM这个丑小鸭。

我或多或少地关注了JRuby的发展和成功的故事,并在Rubyfuza 2015Charles Nutter一起度过了一段美好的时光。后来我觉得很有启发,于是我开始了一项任务,向Ruby项目引入pull requests,这些项目只需要用JRuby来简单的运行测试案例。

快进到2016年

我在2016年11月尝试从头开始构建Rails应用。这是我几个月来第一次在我的机器上尝试Ruby编程。brew upgrade,因此扔掉了我所有的Ruby安装,我甚至对此都没有注意到。

我将在Jozi.rb上展示websockets。

我的出发点是利用Rails回购的反应来获得与Rails的反应的感觉。我已经使用了几个月的重新框架,我很有信心我可以用原始的反应来完成它。

轮子掉下来了,引人注目。

要克隆并运行一个示例应用程序,我需要升级XCode,升级XCode的命令行工具(总计6GB),安装一个新的Ruby版本和bundler,然后在示例应用程序中安装包。简单的对吧?与大多数Rails应用程序一样,示例应用程序依赖于依赖图中的libv8,而它本身的大小就超过1GB。

整个运动花了几个小时。

在玩这个令人印象深刻的演示的时候,我意识到它正在把一个HCMB带到了一个石头剪刀的游戏里。我决定用11月来构建前端,因为我知道11月,而且时间不多了。

同样的,需要更新nvm,安装一个值得尊敬的节点版本,安装ember-cli,生成应用程序并通过npm和凉亭安装依赖项。

我玩了一点,放弃了,相反,我和少数几个来了的人分享了这段经历。这是令人羞愧的,真正令人谦卑的。在这个世界上,我感觉自己像一个陌生人,我已经参与了这么长时间。

回到JVM的声明

你怎么衡量它?

  • 当你下载JVM时,下载文件的大小就是JDK的大小吗?
  • 当你运行JVM时,它会占用很多资源吗?
  • 这些lib库文件是否消耗了大量的磁盘空间?
  • 这是一种正式的部署吗?
  • 它会让你每天的节奏都慢下来吗?

这些问题可以让我们在考虑JVM时,帮助我们减少个人的情感障碍。这些情感和偏见可能会让我们后面付出昂贵的代价,从长远的角度来看对我们不利。

所以,让我们来看看下面的内容。

前期成本真的很高吗?

觉得JVM真的是“太笨重了”可能纯粹是一些墨守成规的人的感觉,而且觉得在前期安装的时候还要花费巨大的成本。你可以拿JDK的~200MB的下载文件与Node或Ruby的15MB的下载文件进行比较。这只是基准线。对于Node和Ruby,你还需要在系统上使用一个C编译器,光这个编译器就已经是数百兆字节。更糟糕的是,生产环境中你可能还得需要一个编译器!

通过这些小的增量步骤,可以将Node和Ruby所需的真实的膨胀量隐藏起来。如果你停止并对其进行评估,不考虑花费的时间,你将会看到200MB的JVM效率更高。



JVM的运行很笨重吗?

JVM非常快,它可能是最快的运行时间之一。随着时间的推移,它会变得越来越快。数千名最聪明的工程师正在努力使其变得更好,而在过去的21年里,更是有了更多的贡献。

它有真正的线程,支持多个内核。你可能惟一需要知道的有用的事情是如何为JVM设置内存,以便在环境的约束中发挥它的魔力。

如何部署到Heroku?java - server -Xmx512m beast.jar。如果这还不够,你可能有收入,还可以向别人请教。哦,或者StackOverflow。

这是Charles和其他JRuby社区的人一直在推动的一件重要事情。如果你不做任何事情,你的应用程序肯定会随着每个JVM的发布而变得越来越快(独立于JRuby的进步)。

磁盘的使用很笨重吗?

我很好奇,因此研究了一下我的~/.m2文件夹,在Clojure开发的9个月里,我只积累了1010MB的依赖关系。甚至还没有十亿字节。

$ du -sh /usr/local/opt/rbenv/versions/2.3.3 ~/.nvm/versions/node/v6.9.1 ~/.m2
690M/usr/local/opt/rbenv/versions/2.3.3
232M/Users/kenneth/.nvm/versions/node/v6.9.1
1010M   /Users/kenneth/.m2

Ruby安装又重新开始了,并且基本上有了这个博客和中间人的需求(我已经在那里做了一个修复工作)。是的,要运行这个静态的博客,并为它提供所需的工具,它需要将近700MB的存储空间。

节点只有11、docpad和保尔安装,我们超过了200MB。

部署是否很笨重?

你很有可能已经猜到我将会说什么了。

你的构建步骤会生成一个单一的JAR文件。它拥有你在其他地方运行的应用程序所需要的一切。你只需将JAR放在需要它的地方,然后加载到JVM就可以了。

不需要将应用程序部署到大型应用程序服务器中,你可以很容易地在JAR文件中打包一个性能良好的HTTP服务器。Node的人会这样做,Ruby的人会这么做,但不知何故,JAR文件无法独立于自己的工作?我以前也这么认为。

就我而言,我不需要在生产环境上运行apt-get install build-essentials,这让我松了一口气。

与JVM的日常工作

我在我的的2012 MacBook Pro上运行了至少5个JVM进程,内存为8GB。我从来没有尝试过同时启动5个Rails应用程序。

为什么同时开启5个?两个用于Datomic(transactor&控制台),一个用于后端API,另一个用于我正在处理的前端。有时我也会有一些在后台运行的自动化测试。我敢肯定,macOS的内存压缩肯定提供了不少帮助,因为这些JVM进程中的大部分都应该将所有相同的字节加载到内存中。



但是,如果你在10个月前告诉我我将会这么做,我就会嘲笑你。在正确的思路下谁会运行5个或更多的JVM进程呢?我可以很自信地说我肯定不是唯一的一个。

哦,但是class paths和其他疯狂的东西呢?由于Clojure提供了伟大工具,没有必要去管这些。这也是你使用npm或bundler的原因,所以你不必去关注这些信息。你可以不关注,但是你可能会有一个不同的问题你没有看到。

交互式解释器的乐趣

如果我必须一直不停的重启JVM实例,毋庸置疑,我的脑子肯定会一团糟的。这种情况在我以前使用JRuby的时候,给我徒增了很多烦恼。幸运的是,使用了Clojure和令人惊讶的交互式解释器以后,我发现只需要奇迹般的重启一个JVM实例就可以了,除非后面由于操作导致出现问题需要重启以外。但这也是一种无能的表现。Figwheel在没有问题的情况下可以连续运行数天。

结论

在将JVM作为目标判断之前,要非常小心。当然可以将Java作为一种语言来判断,但是要将它与虚拟机隔离开来。

我曾经也和你有一样的想法。我曾经认为JVM是个庞然大物。现在我很感谢之前对它的偏见都没有了,让成千上万的人支持它。

决不要把这篇文章看作是“节点的终结”或“Ruby的终结”的标志。读完这篇文章可以给你带来一个全新的视角。如果妮不能切换到JVM进行工作,至少要考虑一下可以做些什么来帮助消除来自于自己膨胀。

谢谢你花这么多时间阅读我的文章。现在去学习一些Clojure,体验什么是Simple Made Easy

评论