java 热编译_为何java一般情况不易热部署?

使用javaagent通过JVMTI接口调用java.lang.instrument.Instrumentation#redefineClasses方法,可以有限地修改已加载的类,关于RedefineClasses接口函数,可参见:JVM(TM) Tool Interface 1.2.1

RedefineClasses() API究竟做了哪些工作,可以贴一段注释:

// The RedefineClasses() API is used to change the definition of one or

// more classes. While the API supports redefining more than one class

// in a single call, in general, the API is discussed in the context of

// changing the definition of a single current class to a single new

// class. For clarity, the current class is will always be called

// "the_class" and the new class will always be called "scratch_class".

//

// The name "the_class" is used because there is only one structure

// that represents a specific class; redefinition does not replace the

// structure, but instead replaces parts of the structure. The name

// "scratch_class" is used because the structure that represents the

// new definition of a specific class is simply used to carry around

// the parts of the new definition until they are used to replace the

// appropriate parts in the_class. Once redefinition of a class is

// complete, scratch_class is thrown away.

//

//

// Implementation Overview:

//

// The RedefineClasses() API is mostly a wrapper around the VM op that

// does the real work. The work is split in varying degrees between

// doit_prologue(), doit() and doit_epilogue().

//

// 1) doit_prologue() is called by the JavaThread on the way to a

// safepoint. It does parameter verification and loads scratch_class

// which involves:

// - parsing the incoming class definition using the_class' class

// loader and security context

// - linking scratch_class

// - merging constant pools and rewriting bytecodes as needed

// for the merged constant pool

// - verifying the bytecodes in scratch_class

// - setting up the constant pool cache and rewriting bytecodes

// as needed to use the cache

// - finally, scratch_class is compared to the_class to verify

// that it is a valid replacement class

// - if everything is good, then scratch_class is saved in an

// instance field in the VM operation for the doit() call

//

// Note: A JavaThread must do the above work.

//

// 2) doit() is called by the VMThread during a safepoint. It installs

// the new class definition(s) which involves:

// - retrieving the scratch_class from the instance field in the

// VM operation

// - house keeping (flushing breakpoints and caches, deoptimizing

// dependent compiled code)

// - replacing parts in the_class with parts from scratch_class

// - adding weak reference(s) to track the obsolete but interesting

// parts of the_class

// - adjusting constant pool caches and vtables in other classes

// that refer to methods in the_class. These adjustments use the

// ClassLoaderDataGraph::classes_do() facility which only allows

// a helper method to be specified. The interesting parameters

// that we would like to pass to the helper method are saved in

// static global fields in the VM operation.

// - telling the SystemDictionary to notice our changes

//

// Note: the above work must be done by the VMThread to be safe.

//

// 3) doit_epilogue() is called by the JavaThread after the VM op

// is finished and the safepoint is done. It simply cleans up

// memory allocated in doit_prologue() and used in doit().

//

题主关于服务器端热部署的需求,现在有很多第三方JVM Agent提供了这种功能,譬如著名的Spring Framework旗下的 Spring-Loaded子项目。看项目说明,可以在运行时修改的class文件的数据范围有了较大的扩展。Spring Loaded is a JVM agent for reloading class file changes whilst a JVM is running. It transforms classes at loadtime to make them amenable to later reloading. Unlike 'hot code replace' which only allows simple changes once a JVM is running (e.g. changes to method bodies), Spring Loaded allows you to add/modify/delete methods/fields/constructors. The annotations on types/methods/fields/constructors can also be modified and it is possible to add/remove/change values in enum types.

Spring Loaded is usable on any bytecode that may run on a JVM, and is actually the reloading system used in Grails 2.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值