(翻译) 如何提升JVM上的开发效率
1. 引言
开发过程中, 代码改动后快速生效是非常重要的.
等待应用冷启动是不可取的, 这会降低开发效率.
在这篇文章中, 我将使用 “特别的JVM参数” 及 “类加载” 技术, 来减少等待时间.
除了不依赖框架的方法, 我还将介绍在SpringBoot应用中的一些技巧.
2. 摘要
- JVM参数
-noverify -XX:TieredStopAtLevel=1
可以减少 30%到45%的应用启动时间 - 然而, 使用"代码热替换"(hot code replacement)来避免应用重启, 是一个更好的办法
- 普通的"代码热替换"是JVM自带的. 只要在IDE中用debug模式启动应用, 代码改动后, 再重新编译一下应用, 就可以立即生效. 但这仅限于方法体内的改动.
- DCEVM 支持字节码, 有更多类型的改动 (如 添加/删除/修改 字段/方法/构造方法), 并在运行的JVM中, 重新加载.
- SpringBoot Developer Tools 提供 自动重启 和 浏览器热加载(LiveLoad). 但是我更喜欢 DCEVM, 因为他更快并保持应用状态.
最后, IDE中的运行配置, 他们提供了 “减少应用启动时间” 和 “类重新加载” 的方法.
3. 通用技巧
如下技巧是不依赖于框架的, 在各JVM应用和IDE中都适用.
3.1 减少应用启动时间
在开发过程, 我们要重启应用好多次. 这非常耗时. 拖累"反馈循环"(feedback cycle).
幸运的是, 我们有如下的JVM参数, 来加快应用的启动速度.
-noverify
或-Xverify:none
: 禁用字节码验证. 这样类加载器, 不会校验字节码的危险性和其他禁止的行为.-XX:TieredStopAtLevel=1
: 限制HotSpot在编译时和运行时的优化.
当然, 在生产环境, 我们不要这样做. 因为, 这会降低应用的安全性及长期的运行性能.
我在SpringBoot测试应用中, 尝试了这些JVM参数, 并记录了应用的启动时间:
How the application has been started | RUN | DEBUG |
---|---|---|
Execute built jar with java -jar | 9.6s | |
Execute main() in the IDE | 10.1s | 12.6s |
Execute main() in the IDE with -noverify -XX:TieredStopAtLevel=1 | 5.7s | 7.3s |
Execute main() in the IDE with IDEA’s Run Configuration “Spring Boot” | 5.7s | 7.3s |
- 所以,
-noverify
或-Xverify:none
, 可显著减少44%的应用启动时间
另, IDE Ultimate, 对SpringBoot应用, 默认自带了, 如上JVM参数.
3.2 代码热替换
实际上, 如果每次改动代码, 都要等6秒钟才生效, 这鸡巴太操蛋!
此外, 我们可能要重新登录, click, click, 回到原来的界面. 这会消耗更多的时间.
这就是"代码热替换"非常适合的场景.
3.2.1 基础的代码热替换
JVM和IDE(idea或eclipse), 提供"基础的代码热替换".
我们只要在IDE中用debug模式启动应用, 代码改动后, 再重新编译一下应用, 就可以立即生效.
这种方法有些限制.
如果, 我们仅仅改动方法体, 那这种方法够用了.
如果, 我们改动方法的签名, 添加/删除 方法或字段, 那就不行了.
3.2.2 用DCEVM改善代码热替换
幸好, 我们有DCEVM.
这一个JVM增强工具. 让我们即使 “新增/删除/修改” 了 “字段/方法/改造方法”. 也能重新加载字节码文件.
简单的安装过程
- 从 https://dcevm.github.io/ 下载 二进制包
- 运行
java -jar DCEVM-<version>-installer.jar
, 会打开一个弹窗, 选中你的JDK, 并点击 “Replace by DCEVM” - 用debug模式启动应用, 添加一个方法, 按
Ctrl+Shift+F9
触发编译, 代码马上生效.
这种方法, 我曾经碰到过"代码热替换"不生效的特殊情况, 但大部分情况下, 他非常好用!
3.2.3 DCEVM的替代方案
- 商业软件 JRebel, 我没有使用过. 我不知道, 他是否足够强大, 价钱是否合适.
- 曾经, 我们使用 Spring-Loaded, 但是, 他不再支持SpringBoot2.0. 这是, 我们为什么要使用DCEVM的原因
4. SpringBoot相关的技巧
Spring提供了强大的Developer Tools, 这在开发工程中, 非常好用.
我重点提下两个功能, Automatic Restart, LiveReload support
- Spring DevTools, 在类路径上的文件发生改变后, 会自动重启应用. 这种启动比冷启动快多了.
- 和LiveReload搭配使用的时候, 尤其nice. 他会在应用重启后, 自动触发浏览器的刷新. (当然, 我们需要给浏览器安装一个插件)
然而, 我更喜欢DCEVM
- 自动重启虽然很快, 但是没有DCEVM的类加载快.
- 自动重启会丢失session. 重启后, 重新登录, 进入相关页面, 查看改动是否生效, 这非常耗时间!
最后, Spring DevTools在开发无状态的SpringBoot应用是不错的, 值的一试.
但是, 我是DCEVM的死忠粉, 因为他更快, 更强, 还能保持应用的状态. 开发溜得飞起!!!