1、JVM基本结构:

*.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/*.jar】ClassLoader

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);

}

编译:

sun.misc.Launcher$AppClassLoader@2a139a55   》系统类加载器

sun.misc.Launcher$ExtClassLoader@7852e922   》扩展类型加载器

Null  》启动类加载器

在jdk的rt.jar下找到java.lang.classLoader类,找到类加载方法:

@parem:name,类的二进制字节流

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 2019年9月15日

*

*/

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, 0, 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();

}

探索JVM底层奥秘ClassLoader源码分析的更多相关文章

  1. 别翻了,这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析【JVM篇二】

    目录 1.什么是类的加载(类初始化) 2.类的生命周期 3.接口的加载过程 4.解开开篇的面试题 5.理解首次主动使用 6.类加载器 7.关于命名空间 8.JVM类加载机制 9.双亲委派模型 10.C ...

  2. JVM 类加载器ClassLoader源码学习笔记

    类加载 在Java代码中,类型的加载.连接与初始化过程都是在程序运行期间完成的. 类型可以是Class,Interface, 枚举等. Java虚拟机与程序的生命周期 在如下几种情况下,Java虚拟机 ...

  3. 探索drf执行流程之APIView源码分析

    Django REST framework 简介 现在新一代web应用都开始采用前后端分离的方式来进行,淘汰了以前的服务器端渲染的方式.而实现前后端分离是通过Django REST framework ...

  4. ClassLoader源码分析与实例剖析

    在之前已经对类加载器做了不少实验了,这次主要是来分析一下ClassLoader的源码,当然主要是先从理解官方给它的注释开始,为之后自定义类加载器打好坚石的基础,下面开始: 而从类的层次结构来看也能感受 ...

  5. Redis学习之底层链表源码分析

    Redis底层链表的源码分析: 一.链表结点的结构(单个结点): // listNode 双端链表节点 typedef struct listNode { // 前置节点 struct listNod ...

  6. JAVA ArrayList集合底层源码分析

    目录 ArrayList集合 一.ArrayList的注意事项 二. ArrayList 的底层操作机制源码分析(重点,难点.) 1.JDK8.0 2.JDK11.0 ArrayList集合 一.Ar ...

  7. [软件测试]网站压测工具Webbench源码分析

    一.我与webbench二三事 Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能.Webbench ...

  8. 网站(Web)压测工具Webbench源码分析

    一.我与webbench二三事 Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能.Webbench ...

  9. [五]类加载机制双亲委派机制 底层代码实现原理 源码分析 java类加载双亲委派机制是如何实现的

      Launcher启动类 本文是双亲委派机制的源码分析部分,类加载机制中的双亲委派模型对于jvm的稳定运行是非常重要的 不过源码其实比较简单,接下来简单介绍一下   我们先从启动类说起 有一个Lau ...

随机推荐

  1. Samba通过ad域进行认证并限制空间大小

    最近正在做单位电脑的AD域管理. 为漫游用户文件,研究配置Samba通过ad域进行认证并限制空间大小. 参考了很多资料,现总结如下: DC:windows server 2016(配置安装域控制器)略 ...

  2. preg_match 第三个参数,

    //请修改变量p的正则表达式,使他能够匹配str中的姓名 $p = '/name:([\w\s]+)/'; $str = "name:steven jobs"; preg_matc ...

  3. QLineEdit 加省略号

    第一种方法: QFontMetrics elidfont(ui->lineEdit->font()); ui->lineEdit->setText (elidfont.elid ...

  4. git删除远程.idea目录

    git删除远程.idea目录 1. 登录 Administrator@USER-20180708AB MINGW32 / (master) $ git config --global user.nam ...

  5. 第07组 Beta冲刺(4/4)

    队名:秃头小队 组长博客 作业博客 组长徐俊杰 过去两天完成的任务:学习了很多东西 Github签入记录 接下来的计划:继续学习 还剩下哪些任务:后端部分 燃尽图 遇到的困难:自己太菜了 收获和疑问: ...

  6. html5+springboot+websocket的简单实现

    环境 window7,IntelliJ IDEA 2019.2 x64 背景:利用IntelliJ来搭建springboot框架,之后来实现websocket的功能.websocket只是实现了画面上 ...

  7. Hive学习(2)

    什么是hive Hive是基于Hadoop的一个数据仓库工具(E抽取T转换L加载),可以将结构化的数据文件映射为一张表,并提供类SQL查询功能 hive的处理流程 ()将HQL语句转化为一组操作符 ( ...

  8. Python学习日记(一) String函数使用

    s = "abcaDa a" s2 = "123a abc ABCSAa s " s3 = "\tas \t\tb123" s4 = ' & ...

  9. linux terminal 快捷键

    删除 快捷键 描述 Ctrl+h 删除光标位置的前一个字符(同 backspace 键功能) Ctrl+* 删除光标位置的前一个字符(同 ctrl+h 组合键功能) Ctrl+d 删除光标位置的一个字 ...

  10. Luogu4827 Crash的文明世界 组合、树形DP

    传送门 又是喜闻乐见的\(k\)次幂求和题目 那么\(S(x) = \sum\limits_{i=1}^n dist(i,x)^k = \sum\limits_{i=1}^n \sum\limits_ ...