`
goodscript
  • 浏览: 73047 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

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

 
阅读更多
先看一个实例

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

  -------------------------------------
package jvm;

import java.net.URL;
import java.net.URLClassLoader;

public class Test {

	public static void main(String[] args) {

		while (true) {
			try {
				ClassLoader parentLoader = Test.class.getClassLoader();
				URLClassLoader loader1 = new URLClassLoader(new URL[] { null }, parentLoader);
				Class<?> cls1 = loader1.loadClass("jvm.A");
				A excel = (A) cls1.newInstance();
				excel.print();
				Thread.sleep(1000 * 3);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}

package jvm;

public class A {
	private String className = "class A";//修改成员变量 class A
	static {
		System.out.println(" static  block initialization ");//修改静态成员变量的打印内容 static  block initialization  change
	}

	//	private String addField = "field 1";//运行时添加一个成员变量
	public void print() {
		System.out.println("hello ");//修改方法内的打印内容hello change
		System.out.println("------------------" + className);
		System.out.println("the end");
	}
	//运行时添加一个成员方法
	//	public void print2() {
	//		System.out.println("hello ");//修改方法内的打印内容hello change
	//		System.out.println("------------------" + className);
	//		System.out.println("the end");
	//	}
}


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

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




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

相关推荐

    一个很简单的过滤器一看就会

    首先,我们来看一下如何创建一个简单的过滤器。在Java中,我们需要实现`javax.servlet.Filter`接口并重写其`doFilter()`方法。这个方法会在每次请求经过时被调用。以下是一个基础的过滤器实现: ```java import ...

    tomcat启动时,在后台自动执行一线程

    从提供的标签“tomcat”和“timer”来看,这个功能主要是利用Tomcat的Servlet机制结合Java的`Timer`类来实现后台定时任务。通过这种方式,我们可以在Tomcat启动后立即开始执行特定操作,并周期性地执行这些操作,...

    linux sysfs 原理及其编程实例

    Linux Sysfs是一个虚拟文件系统,它为用户空间提供了一个接口,可以直接访问和操作Linux内核中的数据结构和对象。Sysfs被设计成一种挂载在`/sys`目录下的文件系统,它允许开发者和系统管理员获取和修改内核的状态...

    linux_driver_hello_world.tar.gz_world

    "linux_driver_hello_world.tar.gz_world"这个压缩包文件显然是一个入门级的Linux内核驱动程序示例,旨在帮助初学者理解驱动开发的基本概念。在这个教程中,我们将探讨Linux内核驱动程序的基础知识,以及如何编写和...

    过滤器的简单示例

    在"filter_demo"这个例子中,很可能包含了一个简单的Filter实现,以及如何配置和测试这个Filter的步骤。可能包括创建Filter类,实现`doFilter()`方法,然后在`web.xml`或使用Java配置来启用这个Filter。此外,可能还...

    字符设备驱动的一些简单代码

    在Linux系统中,字符设备驱动是操作系统...以上代码提供了一个简单的例子,展示了字符设备驱动的基本框架,对于理解和编写自己的字符设备驱动非常有帮助。在实际应用中,需要根据具体的硬件特性进行相应的调整和优化。

    vc++ 开发实例源码包

    C#的一个网页游览的例子 C++自绘窗体的完整代码 注释非常详细,相信会帮助大家设计好自己的个性窗体。 C++_Primer_第4版_中文+英文 原书源码+课后习题答案。 CameraController(云界面) 实现了自绘控件,云端控制...

    C#微软培训资料

    第三章 编写第一个应用程序 .20 3.1 Welcome 程序 .20 3.2 代 码 分 析 .20 3.3 运 行 程 序 .23 .4 添 加 注 释 .25 3.5 小 结 .27 第二部分 C#程序设计基础.28 第四章 数 据 类 型 .28 4.1 值 类 型...

    jsp filter 过滤器判断用户是否登录

    首先,我们来看一下示例中的过滤器类`RightFilter`: ```java import javax.servlet.Filter; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; ...

    Java Web应用开发 52 课堂案例-应用过滤器进行身份验证.docx

    首先,我们来看一下过滤器的核心接口`javax.servlet.Filter`,它包含三个主要方法: 1. `init(FilterConfig filterConfig)`: 这个方法在过滤器被容器加载时调用,用于初始化过滤器。在这个方法中,我们可以获取到`...

    新版Android开发教程.rar

    Android 是一个专门针对移动设备的软件集,它包括一个操作系统,中间件和一些重要的应用程序。 Beta 版 的 Android SDK 提供了在 Android 平台上使用 JaVa 语言进行 Android 应用开发必须的工具和 API 接口。 特性 ...

    JAVA监听器 绝对有用

    每当有新的连接请求到来时,就创建一个新的线程处理器来处理这个连接。 3. **`setUpHandlers` 方法**: 初始化线程池中的连接处理器。 #### 总结 通过以上分析可以看出,监听器是Java Web开发中非常实用的一种技术...

    2021-2022计算机二级等级考试试题及答案No.10739.docx

    - **解析**:此题未给出选项,但从题干来看,可能的问题在于对窗体作用的理解。窗体的主要作用是提供一个用户界面,用于输入、显示和修改数据,也可以用来创建报表。因此,如果问题是询问窗体不能做的事情,可能的...

    广播接收器-BroadcastReceiver 电池电量显示

    在电池电量显示的例子中,我们创建了一个BroadcastReceiver子类,监听`ACTION_BATTERY_CHANGED`广播,然后在`onReceive()`方法中获取并处理电池信息,更新UI展示电量。同时,我们学会了如何根据Activity的生命周期...

    JS实现定时页面弹出类似QQ新闻的提示框

    首先,我们来看一下提供的代码片段。在这个示例中,定义了一个名为`CLASS_MSN_MESSAGE`的JavaScript类,用于创建和管理这些提示框。这个类具有多个属性和方法,如消息的ID、宽度、高度、标题、内容以及定时器设置等...

    编写Java代码制造一个内存溢出的情况

    首先,我们来看一个关于HashSet/HashMap的示例。在Java中,当使用这些数据结构时,键对象必须正确地实现`equals()`和`hashCode()`方法。如果不这样做,可能导致内存中的重复元素,占用额外的内存空间。以下是一个...

    编程魔法师DELPHI 入门实战百例

    - **从实例了解表单的实际应用**:通过具体的例子来学习表单的应用场景。 - **表单的属性、方法、事件**:每个表单都有自己的属性、方法和事件,这些可以用来定制表单的行为。 **4.3 基本表单程序设计** - **单...

    page-flow-react:使用 React 展示页面流动画

    接着,我们来看看CSS动画。CSS动画允许开发者通过关键帧(keyframes)定义一个元素在一段时间内的视觉变化,然后应用到HTML元素上,实现动态效果。在"page-flow-react"中,这些动画效果可能包括淡入淡出、滑动、旋转...

    易语言拦截消息修改窗口类名源码-易语言

    接着,我们来看"修改窗口类名"。窗口类是Windows窗口的模板,包含了窗口的基本属性,如窗口的大小、样式、回调函数等,其中就包括窗口类名。修改窗口类名可以改变窗口的外观和行为,或者实现特定的功能,例如伪装...

Global site tag (gtag.js) - Google Analytics