探索JVM底层奥秘之ClassLoader

it2022-05-05  158

                         探索JVM底层奥秘之ClassLoader

 

JVM 运行流程     1.如何跨平台 (JVM针对不同的平台生成不同的虚拟机) Java源程序通过 Javac编程生成.class文件, 加载到JVM内存的堆中,通过被JVM解析成能被不同平台支持的指令, 2. JVM基本结构    类加载器 ClassLoader   符合要求负责加载到内存中

   执行引擎 execution engine    负责运行 解析 

   运行数据区  核心  

   本地接口  native    被 native 对融合不同开发语言的原生库为JAVA所用  无需重复开发

3.类的装载 : 加载,连接 (验证,准备,解析),初始化,使用,卸载 class存储类的结构  堆中   初始化: 执行类的构造器<clinit> 为类的静态变量和静态代码块初始化值 安源码的顺序执行,如果静态代码块在前,则,只能写不能读 反之没要求 构造器是构造类的 构造方法是实例化对象  先执行构造器, 通过父类的加载器先加载, 4.为什么 类的加载器是双亲委派模型 避免重复加载  首先父类的类加载先加载,如果没找到,在去找发起者的类加载器,

避免重复加载,父类加载器已经加载成功,子类的类加载器无需再次加载    安全,String是根类加载的 Obj

5.有哪些类加载器 常用的

JDK 已有的类加载器 

BootStrapClassloader     JVM的启动加载器 自启的   c++写的   >>主要加载 rt.jar  一堆jar   在java中用Null代替Extensionclassloader       加载%lib/ext/*.jar% Appclassloader       都是继承的    classpath自定义类加载器     自定义的加载路径    重写findclass方法实现自定义类加载器 

6.类加载器在底层存放在什么地方呢?

java.lang.ClassLoader.class

传的是类的二进制字节流 包名加类名

/ /首先,检查是否已经加载了类             Class<?> c = findLoadedClass(name);

 

自定义类加载器   重点是重写findclass方法

import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream;

public class MyclassLoader extends ClassLoader{          private String path; //加载类的路径     private String name;           public MyclassLoader(String path, String name) {         super(); //让系统类加载器成为该类的父类         this.path = path;         this.name = name;     }

    public MyclassLoader(ClassLoader parent,String path, String name) {         super(parent);         this.path = path;         this.name = name;     }

  /*    * 加载定义的类    *     * */     @Override     protected Class<?> findClass(String name) throws ClassNotFoundException {         // TODO Auto-generated method stub         byte[] data = null;         try {             data = readClassFileToByteArray(name);         } catch (IOException e) {             // TODO Auto-generated catch block             e.printStackTrace();         }                  return this.defineClass(name, data, 0, data.length);     }

/*  * 获取。class文件的字节数组  *   *   * */ private byte[] readClassFileToByteArray(String name2) throws IOException {     InputStream is=null;     byte[]returnData=null;     name = name.replaceAll("\\.","/");     String filePath=this.path+ name +".class";     File file=new File(filePath);     ByteArrayOutputStream os=new ByteArrayOutputStream();     try {         is=new FileInputStream(file);         int tmp=0;         while((tmp =is.read())!= -1){             os.write(tmp);         }         returnData=os.toByteArray();     } catch (FileNotFoundException e) {         // TODO Auto-generated catch block         e.printStackTrace();     }finally {         is.close();         os.close();     }     return returnData;     // TODO Auto-generated method stub      }      }  

 

 

 

 

 

 

 


最新回复(0)