debugging 为什么Java的调试热交换仅限于方法内的更改?

swvgeqrz  于 2022-11-30  发布在  Java
关注(0)|答案(4)|浏览(117)

我已经通过了hot deployment tutorial,它是有效的。但是我对限制(第3点)有疑问
热部署仅支持方法实现中的代码更改。如果添加新类或新方法,仍需要重新启动。
基本上,如果我在现有方法中进行更改,我们不需要重新启动服务器,但在添加方法或类的情况下,需要重新启动服务器。

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

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

wz1wpwve

wz1wpwve1#

这个推理相当复杂,只有熟悉JVM及其如何管理内存的人才能完全了解它。Java HotSwap指南中标题为**为什么HotSwap仅限于方法体?**的部分(尽管它实际上是JRebel产品的广告)。
要点:有两个主要因素阻止HotSwap处理类的结构更改:JIT和内存分配。
JVM中的JIT(Just In Time)编译器在类加载并运行几次之后优化字节码,基本上内联了许多调用以提高性能。在类签名和结构可能改变的环境中安全有效地实现该特性将是一个巨大的挑战。
其他的问题是,如果允许改变类结构,内存管理会发生什么。JVM将不得不修改类的现有示例,这意味着将它们重新定位到堆存储的其他部分。更不用说必须重新定位类对象本身。JVM的内存管理已经非常复杂并且高度优化;这样的改变只会增加复杂性并潜在地降低JIT编译器的性能(并可能导致额外的错误)。
我认为可以肯定的是,JVM工程师不愿意在支持这个特性所需的性能和bug足迹之间做出权衡,这就是为什么像JRebel和其他产品会出现的原因。

ybzsozfc

ybzsozfc2#

作为附带说明,说明书本身不受限制。
这只是碰巧一些可用的实现,包括无处不在的Reference Implementation,是有限的。
连接到远程VM后,可以检查它是否允许添加方法或重新定义类。

cigdeys3

cigdeys33#

如果你在smalltalk虚拟机上运行你的java,你可以这样做。Smalltalk基本上一直在做这件事,这也是为什么Smalltalkers倾向于做调试器驱动的开发,作为测试驱动开发的一种上级的形式的原因之一。Smalltalk虚拟机做所需的内存数据结构的清理。在艾略特米兰达的Spur(吱吱声,法老和Cuis)和宝石是懒洋洋地做,但否则您可能必须等待所有对象都被迁移。参考实现javavm可能比您可以在a上运行java的任何smalltalk vm都有更多的优化。时间

a9wyjsp7

a9wyjsp74#

E-Riz提供的答案已经很好地解释了为什么标准的Java HotSwap技术只支持对现有方法的修改,而不支持向类中添加新的类或方法。
然而,正如在相关的SO discussion中所描述的,您实现的热交换级别取决于您使用的工具链。因此,如果您最终添加了JRebel插件,您将能够执行热交换,即使已经添加了新的方法和类。
还有一个项目:Hot Swap Agent-这通常是一个Java代理,可用于运行Java容器,您可以使用几个命令行参数激活它(如quickstart中所述)。

相关问题