`

jvm第六节-类加载器

阅读更多

类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一。它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java Applet 需要从远程下载 Java 类文件到浏览器中并执行。现在类加载器在 Web 容器和 OSGi 中得到了广泛的使用。一般来说,Java 应用的开发人员不需要直接同类加载器进行交互。Java 虚拟机默认的行为就已经足够满足大多数情况的需求了。不过如果遇到了需要与类加载器进行交互的情况,而对类加载器的机制又不是很了解的话,就很容易花大量的时间去调试 ClassNotFoundException和NoClassDefFoundError等异常。本文将详细介绍 Java 的类加载器,帮助读者深刻理解 Java 语言中的这个重要概念。下面首先介绍一些相关的基本概念。
class的装载流程:加载-》连接-》初始化
加载
取得类文件的二进制流,将流转为方法区数据结构
连接
验证:验证文件格式,验证元数据(是否偶父类,是否继承了final类,继承抽象方法的非抽象类是否完全实现了抽象类的方法),字节码验证(比如不符合常量池的长度,比如接口和方法不存在)
准备:准备阶   段final修饰的会赋值,其他的会再初始化的<clinit>中设置
解析:将符号应用换成直接引用如将"java.lang.Object"换成对象对应的指针
初始化
给static变量赋值,static块赋值,<clinit>调用前保证父类<clinit>被调用,<clinit>是线程安全的.
ClassLoader是一个抽象类,他将读入java字节码将类装载到jvm中,可定制,从文件,网络加载class文件,负责类加载过程的加载阶段,连接以后是没关系的
系统中的类加载器:
classLoader默认工作模式-协同同坐,自底向上检查类是否检查,如果从底到上都没有就尝试去加载,加载的方向是反的,启动calssloader先加载,如果启动classloader没加载到,依次往下加载。
 BootStrap ClassLoader 加载  rt.jar   可以用 /-Xbootclasspath用来设置启动类加载器的读取路径
Extension ClassLoader 加载  %JAVA_HOME%/lib/etx/*jar
App ClassLoader 加载 classpaht下文件
有的接口或者工厂类是在rt.jar而实现在程序里的,但bootclassloader无法看到appclassloader里的内容,如何解决了,Thread.setContextClassloader(),通过上下文加载器可以突破双亲模式的缺陷。
下图是我通过改变 BootStrap ClassLoader 的加载路径来加载类代码如下:


 分别把相同的类放在不同的目录下,分别答应不同的类容
public class HelloClassLoader{
	public static void main(String[]args){
		System.out.println("i am in bootclassloader");
	}
}
 如图


 可以证明类加载器是从顶向下加载的
热加载
我们实际的程序在生产环境中可能要显现不能停止程序而实现更新,下面我写了一个热加载的例子

建立4个类代码分别如下:

第一个类:

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class Worker {
public void doit(){
Calendar cd = Calendar.getInstance();
cd.setTime(new Date());

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:MM:ss");
String date=sdf.format(new Date());
System.out.println("hello do it==" + date);
}
}

 
 
第二个类:

 

public class MyClassLoader  extends ClassLoader {
public Class<?> findClass(byte[] b) throws ClassNotFoundException {
        return defineClass(null, b, 0, b.length);
    }
}

 
第三个类:

 

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
/**
 * 自定义类加载
 * @Author:xuehan
 * @Date:2016年2月27日下午5:00:38
 */
public class MyclassLoaderUtils{

// 最后一次被修改时间
long lastmTime = System.currentTimeMillis();

// 判断class文件是否被修改过
public boolean isClassModified(String fileName){
File file = new File(fileName);
if(file.lastModified() - lastmTime > 0){
System.out.println("文件被修改");
lastmTime = System.currentTimeMillis();
return true;
}
return false;
}
 // 从本地读取文件
@SuppressWarnings("unused")
private byte[] getClassBytes(String filename) throws IOException {
File file = new File(filename);
long len = file.length();
lastmTime = file.lastModified();
byte raw[] = new byte[(int) len];
FileInputStream fin = new FileInputStream(file);
int r = fin.read(raw);
fin.close();
return raw;
}
//加载类, 如果类文件修改过加载,如果没有修改,返回当前的
    public Class loadClass(String name) throws ClassNotFoundException, IOException{
    Class c = null;
     if (isClassModified(name)){
        MyClassLoader mc =  new MyClassLoader();
      return c = mc.findClass(getClassBytes(name));
     }
     return c;
    }

第四个类:




import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


/**
 * 虚拟机加载入口的地方
 * @Author:xuehan
 * @Date:2016年2月27日下午5:33:14
 */
public class HelloMain {


@SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args)
throws ClassNotFoundException, IOException, NoSuchMethodException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException, InstantiationException, InterruptedException {
String path = "D:\\Users\\workspace\\jvm\\src\\main\\java\\com\\jvm\\day3\\Worker.class";
MyclassLoaderUtils mc = new MyclassLoaderUtils();
while (true) {
Class c = mc.loadClass(path);
if(null == c){
c = Worker.class;
}
Object o = c.newInstance();
Method m = c.getMethod("doit");
m.invoke(o);
Thread.sleep(2000);
}
}
}

 
我们动态的扫描class文件最后更新时间,确定程序是否被更新了,然后动态的加载。
 
 
 
0
3
分享到:
评论

相关推荐

    JVM(三):类加载机制(类加载过程和类加载器)1

    当类不再被使用且满足特定条件(如类加载器被垃圾收集)时,JVM可能会卸载类,释放其所占的内存。 类加载器在类加载过程中扮演重要角色,它负责找到类的字节流并将其转换为运行时可用的形式。系统提供了几个内置类...

    坚持写博客第一周--java基础知识回顾--jvm类加载1(csdn)————程序.pdf

    - **引导类加载器**(Bootstrap ClassLoader):负责加载JVM运行必需的核心类库,如rt.jar,这部分由C++实现,不在Java代码中直接可见。 - **扩展类加载器**(Extension ClassLoader):加载JRE的lib/ext目录下的...

    JVM图解-JVM指令-JVM原型图.rar

    - 双亲委派模型:当一个类加载器需要加载类时,它会先委托父加载器去尝试加载,只有当父加载器无法加载时,子加载器才会尝试加载。 - 类加载的三个阶段:加载、验证、准备、解析和初始化。 5. **JVM优化**: - ...

    08-Java虚拟机(JVM)面试题-重点.docx

    Class Loader(类加载器) Class Loader 负责将 Java 字节码文件加载到内存中,并将其放在 Runtime Data Area 中的方法区内。它根据给定的全限定名类名来装载 Class 文件。 ### 2. Execution Engine(执行引擎) ...

    深入JVM内核—原理、诊断与优化视频教程-6. 类装载器

    在Java虚拟机(JVM)中,类装载器(ClassLoader)是至关重要的组成部分,它负责查找和加载Java类到JVM内存中。本教程聚焦于深入理解JVM内核,特别是类装载器的原理、诊断与优化。在这个第六部分中,我们将探讨以下几...

    用于测试jvm gc调优-share-jvm-gc.zip

    7. **类加载器管理**:类加载器的不当使用可能导致内存泄漏,因此需要关注类的加载和卸载过程,避免长时间存活的类加载器持有大量不再使用的对象。 8. **代码优化**:避免不必要的大对象创建,减少长生命周期对象,...

    Java的类加载器

    Bootstrap ClassLoader是JVM启动时的第一个类加载器,负责加载JDK的`&lt;JAVA_HOME&gt;/jre/lib`目录下的核心类库。Extension ClassLoader加载`&lt;JAVA_HOME&gt;/jre/lib/ext`目录下的扩展类库。AppClassLoader(也叫System ...

    从JDK源码级别剖析JVM类加载机制

    6. **类加载器与热部署**: 在JDK源码中,类加载机制也为动态替换和更新类提供了可能,这在应用服务器的热部署场景中尤为重要。通过替换类加载器或者重新加载类,可以在不重启应用的情况下更新代码。 7. **双亲...

    jvm系列一java类的加载机制.doc

    总之,Java类的加载机制是JVM的关键组成部分,它涉及到类的获取、验证、准备、解析和初始化,以及类加载器的选择和控制。理解这一机制对于优化应用程序性能、保证代码安全和实现动态扩展具有重要意义。

    Java的jvm相关知识点

    - 类加载器:BootStrapClassLoader、ExtClassLoader、AppClassLoader和自定义ClassLoader,它们各自有特定的加载职责,比如加载核心库、扩展库、第三方库和用户自定义类。 - 双亲委派模型:类加载时先询问父加载器...

    JVM-Tunning-Tools-Introduction

    1. jconsole:提供了一个图形界面来监控JVM的性能和资源消耗,例如内存使用、线程使用情况以及类加载情况。 2. jvisualvm:是一个更为全面的监控和故障排查工具,支持多种插件,可以查看本地和远程JVM的详细性能和...

    Java类加载内幕详细讲解

    #### 六、类加载器的委托模型 类加载器遵循双亲委派模型(Parent Delegation Model),即子类加载器首先请求父类加载器加载类,只有当父类加载器无法完成加载时,子类加载器才会尝试自己加载。这种模型确保了类的...

    01-JVM综合53问(带答案)

    - **职责划分**:每个加载器有特定加载范围,如核心库、扩展库、第三方库和用户自定义类。 - **懒加载**:按需加载,节省内存资源。 5. **双亲委派模型** - 类加载时,先由父加载器尝试加载,若未加载过,则逐级...

    深入研究Java类加载机制 深入研究Java类加载机制

    #### 六、类加载器的应用场景 类加载器在实际应用中有多种应用场景,例如: - **Web容器中的类隔离**:不同的Web应用部署在同一台服务器上时,每个应用都有自己的类加载器,从而实现了类的隔离。 - **热部署**:...

    JVM高级特性与最佳实践(第2版)源代码.zip

    - 自定义类加载器:了解如何编写自己的类加载器,以实现特定的类加载逻辑。 - 双亲委派模型:理解类加载过程中的类查找顺序,以及如何打破这个模型。 5. **JIT编译器**: - 编译触发条件:何时将字节码转化为...

    深入理解Java虚拟机视频教程(jvm性能调优+内存模型+虚拟机原理)视频教程

    第6节杂谈 [免费观看] 00:12:37分钟 | 第7节Java的发展历史00:27:24分钟 | 第8节Java的发展历史续00:02:27分钟 | 第9节Java技术体系00:08:46分钟 | 第10节jdk8的新特性00:07:31分钟 | 第11节lanmbda表达式简介...

    java虚拟机_JVM高级特性与实践最新版

    - 类加载机制:探讨了类加载器如何加载类到JVM,包括启动类加载器、扩展类加载器和应用类加载器的工作流程。 - 字节码执行引擎:解析了字节码指令集,解释如何执行方法和处理异常。 - 内存模型:讲解了堆内存、栈...

    JVM下篇:性能监控与调优篇.7z

    - **JVisualVM**:集成了多种JVM监控功能,如内存、线程、类加载、CPU使用率等。 - **JConsole**:提供GUI界面来监视JVM的性能和诊断问题。 - **JMX(Java Management Extensions)**:允许创建和注册MBeans来...

Global site tag (gtag.js) - Google Analytics