读书人

从一个小例证来看动态卸载class

发布时间: 2012-12-22 12:05:05 作者: rapoo

从一个小例子来看动态卸载class
先看一个实例

使用URLClassLoader每隔3秒钟重复加载A类的class
假如在这3秒钟内我们把class修改了
将会得到什么样的结果:
-------------------------------------



以debug的方式运行、按照下面的修改后运行得到的结果
--------------------------------
1、修改成员变量的值------------动态打印修改后的值
2、修改成员方法的打印内容-------动态打印修改后的值
3、添加成员变量-----------提示警告
4、添加成员方法-----------提示警告
5、删除成员变量-----------提示警告
6、删除成员方法-----------提示警告

根据以上运行结果
class类加载到虚拟机之后无法添加或者删除成员变量及成员方法
但是可以修改成员变量的值或者修改成员方法中的内容




从另一个角度分析

从JVM结构的角度分析,class的结构信息存放在java的方法区内(method Area).包括常量池、字段描述、方法描述等等
常量池:用于存放编译期已可知的常量,这部分内容将在类加载后进入方法区(永久代)存放。但是Java语言并不要求常量一定只有编译期预置入Class的常量表的内容才能进入方法区常量池,运行期间也可将新内容放入常量池。
字段信息和方法描述:在编译时期就已经载入到方法区中。运行时无法对该部分的内容进行修改
方法区可以选择不实现垃圾收集、开源的JVM默认是不实现垃圾收集。
方法区是否需要实现垃圾收集其实是一个很难取舍的问题:
假如对方法区的内存进行垃圾收集、可以想象下次再实例化对象需要重新加载class信息无疑是加重了实例化对象的负担
假如不对方法区的内存进行垃圾收集、则无法动态修改一个class的结构;只能修改一些成员变量、成员方法的内容
相对一些热部署的应用将无法实现

读书人网 >编程

热点推荐