标签:pat 需要 zed 字节码 加载失败 处理过程 申请 protect 结束
对于Java程序员来说,在虚拟机自动内存管理机制下,不再需要像C/C++程序开发程序员这样为内一个new 操作去写对应的delete/free操作,不容易出现内存泄漏和内存溢出问题。
正是因为Java程序员把内存控制权利交给Java虚拟机,一旦出现内存泄漏和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,那么排查错误将会是一个非常艰巨的任务。
顾名思义,类加载器用来加载Java类到Java虚拟机中, Java源文件(.java) 经过Java编译器编译之后就被转换成 字节码文件(.class) ,类加载器就负责读取Java字节代码,并转换成一个 类的实例(java.lang.Class) ,每个这样的实例用来表示一个Java类,这个类由它的类加载器和这个类本身一同确立在Java虚拟机中的唯一性,通过此实例的newInstance()方法就可以创建出该类的一个对象。
Java中的类加载器大致可以分为两类,一类是系统提供的,另外一类是由开发人员编写的
这种类加载的层次关系,称为类加载器的双亲委派模型。
双亲委派模型是指当我们调用类加载器进行类加载时,该类加载器首先请求它的父类加载器进行加载,依次递归。
如果所有的父类加载器都加载失败,则当前类加载器自己进行加载操作。
以下用ClassLoader类的源码进行逻辑分析:
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
//进行类加载操作时首先要加锁,避免并发加载
synchronized (getClassLoadingLock(name)) {
//首先判断指定类是否已经被加载过
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
if (parent != null) {
//如果当前类没有被加载且父类加载器不为null,则请求父类加载器进行加载操作
c = parent.loadClass(name, false);
} else {
//如果当前类没有被加载且父类加载器为null,则请求根类加载器进行加载操作
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
}
if (c == null) {
long t1 = System.nanoTime();
//如果父类加载器加载失败,则由当前类加载器进行加载,
c = findClass(name);
//进行一些统计操作
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
//初始化该类
if (resolve) {
resolveClass(c);
}
return c;
}
}
这里有几个细节需要说明
确保无论使用哪个类加载器加载,最终都会委派给最顶端的启动类加载器加载,从而使得不同加载器加载的类都是同一个类,保障了Java核心类库的安全问题。
相反,如果没有双亲委派模型,由各个类加载器自己加载的话,如果开发者自己写了一个称为java.lang.Object的类并放在classpath下那么系统将会出现很多个不同的Object类,Java类型体系中最基础的行为也就无法保证。
类加载器负责装载编译后的字节码,并加载到运行时数据区,执行引擎则会执行这些字节码。
执行引擎以指令为单位读取Java字节码,它像一个CPU一样,一条一条地执行机器指令,每个字节码指令都由1字节的操作码和附加的操作数来执行任务,完成后就继续执行下一条操作码。
虚拟机实现中,可能会有两种的执行方式:
有些虚拟机值采用一种执行方式,但是有点采用了两种,甚至有可能包含几个不同级别的编译器执行引擎。
所有的Java虚拟机的执行引擎都是一致的:输入的是字节码文件、处理过程是等效字节码解析过程,输出的是执行结果。
这里的坑太深,建议 ->详情请看这里
Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域
这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。
线程共享的: 堆、方法区
线程私有的: (虚拟机)栈、本地方法栈、程序计数器
标签:pat 需要 zed 字节码 加载失败 处理过程 申请 protect 结束
原文地址:https://www.cnblogs.com/zohnn/p/11105347.html