加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

探索JVM底层奥秘ClassLoader源码分析

发布时间:2020-12-15 07:44:58 所属栏目:Java 来源:网络整理
导读:1 、 JVM 基本结构: *.java--------javac 编译 ------*.class-----ClassLoad 加载 ---- 运行时数据区 ------- 执行引擎,接口库 ------ 本地方法库 2、JVM 运行流程: ? public?class?Dome { private?static?int? tem =1; static?{ tem =2; System. out .pr

1JVM基本结构:

*.java--------javac编译------>*.class-----ClassLoad加载---->运行时数据区------->执行引擎,接口库------>本地方法库

2、JVM运行流程:

?

public?class?Dome {

private?static?int?tem=1;

static?{

tem=2;

System.out.println(tem);

}

public?static?void?main(String[] args) {

tem=6;

System.out.println(tem);

}

}

类的装载:

加载,连接(验证,准备,解析),初始化,使用,卸载

Class会保存类的定义或者结构到堆中

初始化:执行类的构造器《clinit》,为类的静态变量赋予正确的初始值

构造器:

1、static变量

2、Static{}语句块

构造方法:实列化对象

3、类加载器双亲委派模型

Bootstrat ClassLoader :启动类加载器(C++,内核)【rt.jar】 ?null

Extension ClassLoader:扩展类加载器---extends->%JAVA_HOME%/lib/ext/*.jarClassLoader

App ClassLoader:系统类加载器 ----extends-->Classpath下加载】ClassLoader扩展类加载器)

自定义类加载器: extends ClassLoader系统类加载器 ---【自定义加载】

public?static?void?main(String[] args) {

//System.out.println(Dome2.class.getClassLoader());

ClassLoader classLoader=Dome2.class.getClassLoader();

while(classLoader!=null) {

System.out.println(classLoader);

classLoader=classLoader.getParent();

}

System.out.println(classLoader);

}

编译:

[email?protected]???》系统类加载器

[email?protected] ??》扩展类型加载器

Null??》启动类加载器

?

jdkrt.jar下找到java.lang.classLoader类,找到类加载方法:

@paremname,类的二进制字节流

??public?Class<?> loadClass(String name) throws?ClassNotFoundException{

????????return?loadClass(name,false);

???}

查找是否有这个类:

有:从父类中加载

无:从BootstrapClass加载

//parent:

? // The parent class loader for delegation

????// Note: VM hardcoded the offset of this field,thus all new fields

// must be added *after* it

private?final?ClassLoader?parent;//父类委派机制 :包含关系

?protected?Class<?> loadClass(String name,boolean?resolve)

????????throws?ClassNotFoundException

????{

????????synchronized?(getClassLoadingLock(name)) {

????????????// First,check if the class has already been loaded

????????????Class<?> c?= findLoadedClass(name);

????????????if?(c?== null) {

????????????????long?t0?= System.nanoTime();

????????????????try?{

????????????????????if?(parent?!= null) { ??????????????????????

?c?= parent.loadClass(name,false);

????????????????????} else?{

????????????????????????c?= findBootstrapClassOrNull(name);

????????????????????}

????????????????} catch?(ClassNotFoundException e) {

????????????????????// ClassNotFoundException thrown if class not found

????????????????????// from the non-null parent class loader

????????????????}

?

????????????????if?(c?== null) {

????????????????????// If still not found,then invoke findClass in order

????????????????????// to find the class.

????????????????????long?t1?= System.nanoTime();

????????????????????c?= findClass(name);?//自定义类加载【回调方法】

?

????????????????????// this is the defining class loader; record the stats

????????????????????sun.misc.PerfCounter.getParentDelegationTime().addTime(t1?- t0);

????????????????????sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);

????????????????????sun.misc.PerfCounter.getFindClasses().increment();

????????????????}

????????????}

????????????if?(resolve) {

????????????????resolveClass(c);

????????????}

????????????return?c;

????????}

????}

被子类重写:

?protected?Class<?> findClass(String name) throws?ClassNotFoundException {

????????throw?new?ClassNotFoundException(name);

}

实列:自定义类加载器

一个本地的Demo.class文件,一个编译环境中的Demo.class文件

测试调用类:

public?class?Dome {

public?Dome() {

System.out.println("A Dome"+Dome.class.getClassLoader());

}

}

需求实现类:

package com.cn.classload;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

/**

?* @Description: 自定义类加载器

?* @ClassName: MyClassLoader

?* @author

?* @date 2019915

?*

?*/

public class MyClassLoader extends ClassLoader {

private String path;// 加载类的路劲

private String name;// 类加载器名称

?

public MyClassLoader(String name,String path) {

super();// 让系统类加载器成为该类的父类

this.name = name;

this.path = path;

}

?

// 父类委托机制:父类加载器

public MyClassLoader(ClassLoader parent,String name,String path) {

super(parent);

this.name = name;

this.path = path;

?

}

?

/**

?* 加载自定义的ClassLoader Title: findClass Description:

?*

?* @param name:包路径

?* @return

?* @throws ClassNotFoundException

?* @see java.lang.ClassLoader#findClass(java.lang.String)

?*

?*/

@Override

protected Class<?> findClass(String name) throws ClassNotFoundException {

?

byte[] data = readClassFileToByteArray(name);

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

}

?

/**

?* Title: toString Description:

?*

?* @return

?* @see java.lang.Object#toString()

?*

?*/

@Override

public String toString() {

// TODO Auto-generated method stub

return this.name;

}

?

/**

?* @Description: 获取.class文件的字节数组

?* @Title: readClassFileToByteArray

?* @date 2019-09-15 17:27

?* @param @param name2

?* @param @return 参数

?* @return byte [] 返回类型

?* @throws @return byte []

?* @param name2

?* @return

?*/

private byte[] readClassFileToByteArray(String name) {

InputStream iStream = null;

byte[] returnData = null;

name = name.replaceAll(".","/");

String filePath = this.path + name + ".class";

System.out.println("路径:"+filePath);

File file = new File(filePath);

ByteArrayOutputStream os = new ByteArrayOutputStream();

try {

iStream = new FileInputStream(file);

int tmp = 0;

while ((tmp = iStream.read()) != -1) {

os.write(tmp);

?

}

returnData = os.toByteArray();

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

} finally {

if (os != null) {

try {

os.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

if (iStream != null) {

try {

iStream.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

return returnData;

}

}

?

测试类:

public?static?void?main(String[] args) throws?ClassNotFoundException,InstantiationException,IllegalAccessException {

MyClassLoader zhangfeimyClassLoader=new?MyClassLoader("zhangfei","D:/com/cn/classload/");

//MyClassLoader wukongmyClassLoader=new MyClassLoader(zhangfeimyClassLoader,"wukong","D:/com/cn/classload/");//现在张飞是悟空的父类委派加载器输出的就是编译环境中的Dome.class文件

?

MyClassLoader wukongmyClassLoader=new?MyClassLoader(null,"wukong","D:/com/cn/classload/");//这里父类没有就是用自定义的加载器输出的就是本地磁盘上的Dome.class文件

Class<?> c=wukongmyClassLoader.loadClass("Dome");

c.newInstance();

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读