话不多说,先上图。

***.class文件执行大概就是这样来走的。我们都知道我们的java文件经过编译以后会生成对应的class文件。先经过类装载子系统,然后塞进运行时内存模型的元空间,开始执行方法,对象放在堆,线程开辟栈空间,程序计数器控制执行顺序。字节码执行引擎整体调控程序计数器,走你。。。大概就是这样的。我们先来看一下类装载子系统是如何工作的。

  类装载子系统大概分为,验证->准备->解析->初始化。笼统的来说就这个4个步骤。

1,验证:验证我们的编译文件(字节码文件)是否正确。

2,准备:给予类的静态常量开辟堆空间。并且赋予默认值。对象也在这个时候放置在堆空间,并且给予空值。

3,解析:将符号引用替换为直接引用,该阶段会把一些静态方法(符号引用,比如main()方法)替换为指向数据所存内存的指针或句柄等(直接引用),这是所谓的静态链接过程(类加载期间完成),动态链接是在程序运行期间完成的将符号引用替换为直接引用。就像是我们把main转化为001,将()转化为002,将这一系列的编码存在堆上。

4,初始化,将第3步的静态常量(或对象)赋值,执行静态代码块。

类的加载器大致分为,启动类加载器,扩展类加载器,应用类加载器和自定义加载器,后面我们会说如何实现自己的类加载器。

启动类加载器是用来加载java自身的lib包的。用C语言实现的,我们是看不到的。

扩展类加载器顾名思义,是加载java的扩展包的。加载ext包下的jar包

然后就是我们的应用加载器,来执行我们一行行代码的。

最后才是我们的自定义加载器。我来看一段代码。

import com.sun.crypto.provider.DESKeyFactory;

public class Main {

    public static void main(String[] args) {
System.out.println(String.class.getClassLoader());
System.out.println(DESKeyFactory.class.getClassLoader().getClass().getName());
System.out.println(Main.class.getClassLoader().getClass().getName());
}
}

输入如下:

null
sun.misc.Launcher$ExtClassLoader
sun.misc.Launcher$AppClassLoader Process finished with exit code 0

三种加载器就是这样的。

 双亲委派机制:

  我们知道一个基础的知识,就是我们新建的java.lang.String是无法加载的,就是加载过程的双亲委派机制限制了我们自定义重写java本来的代码。

双亲委派是为了阻止我们重写java内部的类,做到了沙箱安全的目的。

  大概就是这样来实行的。上图:

自定义加载器会优先拿到要加载的文件,但是他不会去马上加载。而是直接交给应用类加载器,应用类加载器也不会管,继续向上走,交给扩展类加载器,他也不管,继续向上走,交给启动类加载器,没办法了,启动类加载器没法继续向上交付了。自己先试试可以加载吗?可以加载就加载,加载不了退返给扩展类加载器,扩展类看到是推回来的,试试吧。可以加载吗?可以加载就加载,加载不了退返给应用类加载器,应用类加载器可以加载就加载,加载不了退返给自定义加载器。这样一个由下到上,谁也不管。逐个去尝试往下推的方法去加载。好久就是为了防止你重写java内部的类。

  这里简单说一下自定义加载器。

我们只要重写com.sun.org.apache.bcel.internal.util;包下的ClassLoader类的findClass方法,最后调用defineClass方法。就可以实现我们的自定义加载器。

  这回我们再回过头来看上一篇博客的tomcat打破双亲委派机制也就懂得是怎么回事了吧。不懂的评论留言吧。就说到这里,我们下一次说一下jvm运行时内存模型那一块。

写的这么不好的文章能坚持读到最下面确实挺不易的,贡献一个小技巧,来看类是否真的被加载了。

最进弄了一个公众号,小菜技术,欢迎大家的加入

java架构之路-(JVM优化与原理)JVM类的加载机制的更多相关文章

  1. [转帖]java架构之路-(面试篇)JVM虚拟机面试大全

    java架构之路-(面试篇)JVM虚拟机面试大全 https://www.cnblogs.com/cxiaocai/p/11634918.html   下文连接比较多啊,都是我过整理的博客,很多答案都 ...

  2. jvm系列(一):java类的加载机制

    java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装 ...

  3. JVM(1):Java 类的加载机制

    原文出处: 纯洁的微笑 java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang. ...

  4. jvm系列 (五) ---类的加载机制

    类的加载机制 目录 jvm系列(一):jvm内存区域与溢出 jvm系列(二):垃圾收集器与内存分配策略 jvm系列(三):锁的优化 jvm系列 (四) ---强.软.弱.虚引用 我的博客目录 什么是类 ...

  5. 深入java虚拟机学习 -- 类的加载机制

    当看到"类的加载机制",肯定很多人都在想我平时也不接触啊,工作中无非就是写代码,不会了可以百度,至于类,jvm是怎么加载的我一点也不需要关心.在我刚开始工作的时候也觉得这些底层的内 ...

  6. 深入java虚拟机学习 -- 类的加载机制(续)

    昨晚写 深入java虚拟机学习 -- 类的加载机制 都到1点半了,由于第二天还要工作,没有将上篇文章中的demo讲解写出来,今天抽时间补上昨晚的例子讲解. 这里我先把昨天的两份代码贴过来,重新看下: ...

  7. Jvm类的加载机制

    1.概述 虚拟机加载Class文件(二进制字节流)到内存,并对数据进行校验.转换解析和初始化,最终形成可被虚拟机直接使用的Java类型,这一系列过程就是类的加载机制. 2.类的加载时机 类从被虚拟机加 ...

  8. java架构之路-(面试篇)JVM虚拟机面试大全

    下文连接比较多啊,都是我过整理的博客,很多答案都在博客里有详细说明,理解记忆是最扎实的记忆.而且我的答案不一定是最准确的,但是我的答案不会让你失望,而且几乎每个答案都是问题的扩展答案. 1.JVM内存 ...

  9. jvm系列一、java类的加载机制

    一.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构 ...

随机推荐

  1. 【Edu 67】 补题记录

    CF1187D. Subarray Sorting 想要把一个数x换到前面,x一定是小一点的值.由于B串是固定的,A串可调整,我们可以遍历B数组,对于B[i],找到对于在A数组的位子pos,判断1-p ...

  2. 2019杭电多校 hdu6659 Acesrc and Good Numbers

    http://acm.hdu.edu.cn/showproblem.php?pid=6659 题意:给你d,x,让求满足f(d,n)=n的最大n(n<=x),其中f(d,n)表示数字d在从1到n ...

  3. codeforces 879 D. Teams Formation(思维)

    题目链接:http://codeforces.com/contest/879/problem/D 题意:这题题意我反正是看了很久,可能是我的理解能力有点差,就是将一个数组倍增m倍然后将连续的相同的k个 ...

  4. Features Track 2018徐州icpc网络赛 思维

    Morgana is learning computer vision, and he likes cats, too. One day he wants to find the cat moveme ...

  5. codeforces 456 E. Civilization(并查集+数的直径)

    题目链接:http://codeforces.com/contest/456/problem/E 题意:给出N个点,M条边,组成无环图(树),给出Q个操作,操作有两种: 1 x,输出x所在的联通块的最 ...

  6. hdu Sumsets

    Farmer John commanded his cows to search for different sets of numbers that sum to a given number. T ...

  7. java基础面试(二)

    最近有搜了几个面试题,大家一起来探讨一下. 1.Oracle 的分页 --分页查询一 select * from (select a1.*,rownum rn from (select * from ...

  8. HDU 1015 Safecracker (DFS)

    题意:给一个数字n(n<=12000000)和一个字符串s(s<=17),字符串的全是有大写字母组成,字母的大小按照字母表的顺序,比如(A=1,B=2,......Z=26),从该字符串中 ...

  9. moco 入门及问题解决

    废话不多说 下载: http://repo1.maven.org/maven2/com/github/dreamhead/moco-runner/ 选择最新版本下载jar包 启动: 1:在本地jar包 ...

  10. 【LeetCode】BFS 总结

    BFS(广度优先搜索) 常用来解决最短路径问题. 第一次便利到目的节点时,所经过的路径是最短路径. 几个要点: 只能用来求解无权图的最短路径问题 队列:用来存储每一层便利得到的节点 标记:对于遍历过的 ...