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. MUD游戏开发教程视频

    MUD游戏开发教程视频 https://space.bilibili.com/476328540/channel/detail?cid=91187

  2. 取消Windows server 2008关机提示备注的方法

    打开“开始”-“运行”,在“打开”一栏中输入“gpedit.msc”命令打开组策略编辑器,依次展开“计算机配置”→“管理模板”→“系统”,双击右侧窗口出现的“显示‘关闭事件跟踪程序’”,将“未配置”改 ...

  3. [LeetCode] 516. Longest Palindromic Subsequence 最长回文子序列

    Given a string s, find the longest palindromic subsequence's length in s. You may assume that the ma ...

  4. ehcache和redis的区别及适用场景

    区别: (1)Redis 独立程序,是通过socket访问到缓存服务,效率比ecache低,比数据库要快很多,处理集群和分布式缓存方便,有成熟的方案 (2)Ehcache 直接在jvm虚拟机中缓存,速 ...

  5. 「模拟赛20191019」A 简单DP

    题目描述 给一个\(n\times m\)的网格,每个格子上有一个小写字母. 对于所有从左上角\((1,1)\)到右下角\((n,m)\)只向下或向右走的路径构成的集合,判断是否存在两条走法不同的路径 ...

  6. 08 Spring框架的概念、优势、体系结构、耦合性和IOC(反转控制)

    1.spring介绍 Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control: 反转控制)和 AOP(Aspect ...

  7. Integer的parseInt和valueOf的区别

    先来看一下下面这段代码 String s = "1"; System.out.println(Integer.valueOf(s)); System.out.println(Int ...

  8. 关于MSVCR100.dll、MSVCR100d.dll、Msvcp100.dll、abort()R6010等故障模块排查及解决方法

    一.常见故障介绍 最近在开发相机项目(项目细节由于公司保密就不介绍了),程序运行5个来月以来首次出现msvcr100.dll故障等问题,于是乎开始了分析之路,按照度娘上的一顿操作,期间也是出现了各种不 ...

  9. stm32F103片上串口USART1通信实验

    硬件说明:如原理图所示, 103的PA10 PA11分别接CP2102usb转串口芯片的TXD RXD引脚.CP2102芯片是将串口和电脑USB接口进行了转接,方便应用灵活. 片上串口驱动代码如下. ...

  10. webpack4打包报错ERROR in multi ./src/main.js dist/bundle.js

    webpack打包测试: 上边将mode01.js模块及main.js主文件编写完成,下边使用webpack对这些js文件进行打包 1.进入程序目录,执行webpack main.js build.j ...