一.首先先说一下java虚拟机的生命周期:

1.执行了system.exit();

2.程序正常执行结束;

3.程序在执行过程中遇到了异常或错误而终止;

4.由于操作系统出现错误而导致java虚拟机进程终止;

二:ClassLoader

1.几种类加载器:

(1).Bootstrap ClassLoader:这个主要加载JVM自身工作需要的类,是由JVM自己控制的,需要加载哪个类,怎么加载都是有JVM负责的!别人访问不到这个类,所以这个ClassLoader是不遵守类加载规则的,因为它仅仅是个工具,既没有更高级的父加载器,也没有子加载器! 加载源:JRE/lib/rt.jar或者是bootclasspath选项制定的jar;

(2).ExtClassLoader:  它是JVM的一部分,它加载的目标是System.getProperty("java.ext.dirs");

(3).AppClassLoader:这个类跟我们平时打交道的比较多,在System.getProperty("java.class.path");的目录下的类都可以被这个类加载,ExtClassLoader是它的父加载器。

2.JVM记载Class的两种方式:

(1).隐式加载:通过JVM来自动加载需要的类到内存中。如:当我们引用某个类时,JVM解析这个类不再内存中,就会自动把该类加载到内存中!

(2).显式加载:通过调用ClassLoader来加载一个类的方式。下面的例程中我将会自己下个类加载器。

3.等级加载机制(父委托机制):

通过上图可以知道:当一个.class文件被JVM加载的时候,JVM首先判断是否被记载,如果被加载就结束加载过程;否则的话,就开始寻找本加载器的父类加载器,父类加载器也是先判断是否已经被加载,若没有被加载&&本加载器没有父类加载器了,就会判断应不应该由我来加载,若不应该,就会传递给它的子加载器,以此类推......

一开始我不明白,为什么JVM的类加载机制为什么要设计的这么麻烦!现在可能已经想通了:它是为了使类能够已正确的方式被应该加载它的类加载器加载!

三:.class文件如何被加载到JVM中:

(1).加载:

类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。【–从本地系统中直接加载 ,–通过网络下载.class文件 ,–从zip,jar等归档文件中加载.class文件, –从专有数据库中提取.class文件, –将Java源文件动态编译为.class文件 】

(2).验证:

类被加载后,就进入连接阶段。连接就是将已经读入到内存的类的二进制数据合并到虚拟机的运行时环境中去。【类文件的结构检查, 语义检查, 字节码验证, 二进制兼容性的验证 】

(3).准备:

为类的静态变量分配内存(方法区),并将其初始化为默认值!

(4).解析:

解析阶段是把类的二进制数据中的符号引用替换为直接应用【给Java语言带来了强大的动态扩展能力】。如:

public void sayHello(){

tdd.say();

}

在本类中,包含一个对tdd的符号引用,它是由say()方法的全名和相关描述符组成。在解析阶段,JVM会把这个符号引用替换为一个指针,改指针指向tdd类的say方法在方法区的内存位置,这个指针就是直接引用!

(5).初始化:

Java程序对类的使用方式可分为两种 :

主动使用【创建类的实例 ,访问某个类或接口的静态变量,或者对该静态变量赋值, 调用类的静态方法, 反射(如Class.forName(“com.shengsiyuan.Test”)), 初始化一个类的子类 ,Java虚拟机启动时被标明为启动类的类(Java Test) 】

被动使用

所有的Java虚拟机实现必须在每个类或接口被Java程序“首次主动使用”时才初始化他们!

在初始化阶段,JVM执行类的初始化语句,为类的静态变量赋予初始值。在程序中,静态变量的初始化有俩种方式:(1).在静态变量的声明处进行初始化;(2)在静态代码中进行初始化。

四:常见类加载错误分析:

(1)ClassNotFoundException:

JVM要加载指定文件的字节码到内存中,并灭有找到这个文件对应的字节码,也就是这个文件不存在!检查当前的classpath下面有没有这个文件!

(2)NoClassDefFoundError:

这个有可能是你隐式加载类的时候,没有写全类名!NoClassDefFoundError的可能情况是:new 关键字,属性引用某个类,继承了某个接口或者类等等...

(3)UnsatisfiedLinkError:

如果不小心把JVM中的某个lib包删掉的话,就有可能出现这种情况。

五:实现自己的类加载器:

public class PathClassLoader extends ClassLoader {

private byte[] getData(String className) {

String path = "D:/workpace/test/build/classes/";

String namePath = className.replace(".", "/");

String classpath = path + namePath + ".class";

try {

InputStream is = new FileInputStream(new File(classpath));

ByteArrayOutputStream stream = new ByteArrayOutputStream();

byte[] buffer = new byte[2048];

int num = 0;

while ((num = is.read(buffer)) != -1) {

stream.write(buffer, 0, num);

}

return stream.toByteArray();

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

protected Class> findClass(String name) throws ClassNotFoundException {

if (name != null) {

byte[] data = getData(name);

if (data == null) {

throw new ClassNotFoundException();

} else {

return defineClass(name, data, 0, data.length);

}

} else {

return super.loadClass(name);

}

}

public static void main(String[] args) throws ClassNotFoundException,

IllegalArgumentException, IllegalAccessException,

InvocationTargetException, InstantiationException,

SecurityException, NoSuchMethodException {

PathClassLoader pathClassLoader = new PathClassLoader();

Class myClass = pathClassLoader.findClass("com.classloader.HelloWorld");

System.out.println(myClass);

Object obj = myClass.newInstance();

Method method = myClass.getMethod("say", null);

method.invoke(obj, null);

}

public class HelloWorld {

public void say(){

System.out.println("hello,world");

}

}

打印结果:

class com.classloader.HelloWorld

hello,world

font

java虚拟机加载类_java虚拟机之类加载机制(一)相关推荐

  1. java重新加载类_java重新加载类的探寻

    java重新加载类的探寻 首先上结论:java类加载器不支持重新加载类.如果想重新加载,那就新建一个类加载器. 接下来慢慢讲: 项目背景 在近日做的一个项目中,有一个动态获取用户输入的代码,并进行运行 ...

  2. java web 加载类_Java中用ClassLoader载入各种资源(类、文件、web资源)的方法

    lassLoader主要对类的请求提供服务,当JVM需要某类时,它根据名称向ClassLoader要求这个类,然后由ClassLoader返回这个类的class对象. ClassLoader负责载入系 ...

  3. java初始化加载类_Java 类的加载和初始化

    直接从书上抄来的,自己写一遍加深印象 类的加载 加载就是通过指定的类全限定名,获取此类的二进制字节流(可以是clazz文件或者直接内存读取或者远程网络,jar包等),然后将此二进制字节流转化为方法区的 ...

  4. java 获得 加载类_java 类的加载,与获得相应的方法

    package com.yxy.core; import java.lang.reflect.Method; import java.lang.reflect.Type; import static ...

  5. java 线程加载类_java JVM-线程上下类加载器

    public class One { public static void main(String[] args) throws Exception { ClassLoader loader=One. ...

  6. 怎么加载文件_Java虚拟机从入门到入土之JVM的类加载机制

    作者:六脉神剑 转载于:https://juejin.im/post/5e1aaf626fb9a0301d11ac8e JVM总体概述 JVM总体上是由 类装载子系统(ClassLoader) 运行时 ...

  7. java动态加载类 框架_java运用RMI框架类的动态加载不成功

    最近在看<java网络编程精解>,第11章中用RMI动态加载类,可怎么试都不成功,求大神解答 1. 我先在C盘下启动了rmiregistry注册表,如果部署成功注册表应该会从codebas ...

  8. java 启动加载顺序_Java 程序的加载运行过程 | 学步园

    为了叙述方便,我写了个小例子 class Three{ private static int s3 = getS3(); private int y = getY(); public Three(){ ...

  9. Java如何加载类的呢?

    JVM加载类 首先查看内存中是否存在该类(内存中所有类都是以Class的实例对象存在),若不存在则会通过环境变量中的路径值在电脑或者其它设备的硬盘中找到该类(即.class文件),然后JVM会将其读取 ...

最新文章

  1. 第三章 线性代数回顾-机器学习老师板书-斯坦福吴恩达教授
  2. 动态备份SQL-SERVER数据库——SQLDMO
  3. java进行md5运算(Java类函数调用)
  4. 《四世同堂》金句摘抄(六)
  5. 团队项目—第二阶段第三天
  6. 从Linux服务器端下载文件Win客户端
  7. php基本类,php入门一之十大基本类型
  8. Mybatis MySQL批量更新
  9. 云原生2.0时代,华为云DevOps立体运维实践
  10. SQL SERVER事务处理
  11. request与在php安全,request导致的安全性问题分析
  12. HDU Today--hdu2112
  13. 裴(pei)蜀定理 知识点
  14. OpenCV下载驿站(解决github下载问题,解决OpenCV官网下载较慢)
  15. 算法图解————K 近邻算法
  16. exchange创建邮箱组_Exchange 2013学习笔记四:新建用户邮箱
  17. 读后感—肿瘤基因检测行业会好吗
  18. 人脸识别、深度学习优秀设计(毕业专业指导)
  19. GIC spec之ITS和LPI中断1
  20. 一个“后浪”的狂欢,一群中年人的孤单!

热门文章

  1. react native改变app的图标和名称
  2. vtun 接收和发送数据流程图
  3. 天津大学计算机科学学院夏令营,天津大学计算机科学与技术学院(专业学位)计算机技术保研夏令营...
  4. HTML5唐四薪,8文件存取组件课件.ppt
  5. qa 芯片测试_芯片测试术语介绍CP、FT、WAT
  6. axios delete有请求体吗_封装 axios 取消重复请求
  7. 手机cpu排行_鲁大师手机芯片排行榜:麒麟990第四,骁龙855第五!
  8. 小学四年级下册计算机考试试题,四年级信息技术下学期测试题
  9. 软工专硕考研_分析|华北电力(北京)大学20计算机考研报录分析!电子信息复试狂刷114人,软工专硕复试录取高达1:4.7!...
  10. 二、分布式文件系统HDFS及其简单使用