26

我已经完成了热部署教程并且它有效。但我对限制有疑问(第 3 点),即

热部署仅支持方法实现中的代码更改。如果添加新类或新方法,仍然需要重新启动。

基本上为什么如果我对现有方法进行更改但在添加方法或类时需要重新启动服务器。

我理解它是如何工作的:-当我对现有方法进行更改或引入新方法时,Eclipse 会将文件放置在网络服务器下的正确位置。如果类加载器已经在 perm gen 空间中加载了类,它将从 permgen 空间中卸载它并在内部加载新的而不需要重新启动服务器,以便反映新的更改(字节码)。那是对的吗 ?

如果是,为什么热部署不适用于新方法和新类文件?

4

4 回答 4

27

推理非常复杂,只有对 JVM 及其如何管理内存有深入了解的人才能真正完全了解。这里有一个不错的解释:Java HotSwap 指南(虽然它实际上是 JRebel 产品的广告)——滚动到标题为“为什么 HotSwap 仅限于方法体?”的部分?.

要点:有两个主要因素阻止 HotSwap 处理类的结构更改:JIT 和内存分配。

JVM 中的 JIT (Just In Time) 编译器在类加载并运行几次后优化字节码,基本上内联了许多调用以提高性能。在类签名和结构可以更改的环境中安全有效地实现该功能将是一项重大挑战。

如果允许更改类结构,其他问题围绕着内存管理会发生什么。JVM 将不得不修改现有的类实例,这意味着将它们重新定位到堆存储的其他部分。更不用说必须自己重新定位类对象。JVM 的内存管理已经非常复杂且高度优化;此类更改只会增加复杂性并可能降低 JIT 编译器的性能(并可能导致额外的错误)。

我认为可以安全地假设 JVM 工程师不愿意在支持此功能所需的性能和错误足迹上进行权衡。这就是 JRebel 等产品应运而生的原因。

于 2016-01-25T15:27:45.517 回答
3

作为旁注,规范本身不受限制

它只是碰巧一些可用的实现,包括无处不在的参考实现,是有限的。

连接到远程 VM 后,您可以检查它是否允许 添加方法重新定义类

于 2016-01-29T19:10:15.790 回答
2

如果你在 smalltalk vm 上运行你的 java,你可以。Smalltalk 基本上一直在这样做,这也是 Smalltalkers 倾向于将调试器驱动开发作为测试驱动开发的一种优越形式的原因之一。Smalltalk vm 对内存数据结构进行必要的清理。在 Eliot Miranda 的 Spur(用于 Squeak、Pharo 和 Cuis)和 Gemstone 中,这是懒惰地完成的,否则您可能必须等待所有对象都被迁移。参考实现 java vm 可能比任何可以在 atm 上运行 java 的 smalltalk vm 具有更多的优化

于 2016-01-30T16:10:10.040 回答
0

E-Riz 提供的答案已经很好地解释了为什么标准 Java HotSwap 技术只支持对现有方法的修改而不支持向类添加新类或方法的原因。

但是,正如相关SO 讨论中所述,您实现的热交换级别取决于您使用的工具链。因此,如果您最终添加了 JRebel 插件,即使添加了新的方法和类,您也可以执行热交换。

还有另一个项目:Hot Swap Agent - 这通常是一个 Java 代理,可用于运行您的 Java 容器,您可以使用几个命令行参数激活它(如快速入门中所述)。

于 2016-01-31T11:51:44.703 回答