1.Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的, 类装载器所做的工作实质是把类文件从硬盘读取到内存中

2.java中的类大致分为三种:     1.系统类     2.扩展类     3.由程序员自定义的类

3.类装载方式,有两种     1.隐式装载, 程序在运行过程中当碰到通过new 等方式生成对象时,隐式调用类装载器加载对应的类到jvm中,     2.显式装载, 通过class.forname()等方法,显式加载需要的类   隐式加载与显式加载的区别:     两者本质是一样?,     ?

4.类加载的动态性体现     一个应用程序总是由n多个类组成,Java程序启动时,并不是一次把所有的类全部加载后再 运行,它总是先把保证程序运行的基础类一次性加载到jvm中,其它类等到jvm用到的时候再加载,这样的好处是节省了内存的开销,因为java最早就是为嵌入式系统而设计的,内存宝贵,这是一种可以理解的机制,而用到时再加载这也是java动态性的一种体现

5.java类装载器     Java中的类装载器实质上也是类,功能是把类载入jvm中,值得注意的是jvm的类装载器并不是一个,而是三个,层次结构如下:       Bootstrap Loader  - 负责加载系统类             |           - - ExtClassLoader  - 负责加载扩展类                           |                       - - AppClassLoader  - 负责加载应用类         为什么要有三个类加载器,一方面是分工,各自负责各自的区块,另一方面为了实现委托模型,下面会谈到该模型

6. 类加载器之间是如何协调工作的       前面说了,java中有三个类加载器,问题就来了,碰到一个类需要加载时,它们之间是如何协调工作的,即java是如何区分一个类该由哪个类加载器来完成呢。 在这里java采用了委托模型机制,这个机制简单来讲,就是“类装载器有载入类的需求时,会先请示其Parent使用其搜索路径帮忙载入,如果Parent 找不到,那么才由自己依照自己的搜索路径搜索类”,注意喔,这句话具有递归性 下面举一个例子来说明,为了更好的理解,先弄清楚几行代码: Public class Test{     Public static void main(String[] arg){       ClassLoader c  = Test.class.getClassLoader();  //获取Test类的类加载器         System.out.println(c);        ClassLoader c1 = c.getParent();  //获取c这个类加载器的父类加载器         System.out.println(c1);       ClassLoader c2 = c1.getParent();//获取c1这个类加载器的父类加载器         System.out.println(c2);   } } 把以上代码存到d:\my 文件夹下,直接编译,然后在dos模式下运行 D:\my\java Test     。。。AppClassLoader。。。     。。。ExtClassLoader。。。     Null

D:\my

注: 。。。表示省略了内容 可以看出Test是由AppClassLoader加载器加载的 AppClassLoader的Parent 加载器是 ExtClassLoader

但是ExtClassLoader的Parent为 null 是怎么回事呵,朋友们留意的话,前面有提到Bootstrap  Loader是用C++语言写的,依java的观点来看,逻辑上并不存在Bootstrap  Loader的类实体,所以在java程序代码里试图打印出其内容时,我们就会看到输出为null 【注:以下内容大部分引用java深度历险】 弄明白了上面的示例,接下来直接进入类装载的委托模型实例,写两个文件,如下: 文件:Test1.java Public class Test1{     Public static void main(String[] arg){         System.out.println(Test1.class.getClassLoader());         Test2 t2 = new Test2();         T2.print();   } }

文件: Test2.java Public class Test2{     Public void prin(){         System.out.println(this.getClass().getClassLoader());     } }

这两个类的作用就是打印出载入它们的类装载器是谁, 将这两个文件保存到d:\my目录下,编译后,我们在复制两份,分别置于  <JRE所在目录>\classes下(注意,刚开始我们的系统下没有此目录,需自己建立) 与  <JRE所在目录>\lib\ext\classes下(同样注意,开始我们的系统下也没此目录,手工建立),  然后切换到d:\my目录下开始测试,

测试一: <JRE所在目录>\classes下 Test1.class Test2.class

<JRE所在目录>\lib\ext\classes下 Test1.class Test2.class

D:\my下 Test1.class Test2.class

dos下输入运行命令,结果如下: D:\my>java Test1 Null Null

D:\my>          从输出结果我们可以看出,当AppClassLoader要载入Test1.class时,先请其Parent,也就是ExtClassLoader来载 入,而ExtclassLoader又请求其Parent,即Bootstrap Loader来载入Test1.class. 由于  <JRE所在目录>\Classes目录为Bootstrap Loader的搜索路径之一,所以Bootstrap  Loader找到了Test1.class,因此将它载入,接着在Test1.class之内有载入Test2.class的需求,由于  Test1.class是由Bootstrap Loader所载入,所以Test2.class内定是由Bootstrap  Loader根据其搜索路径来找,因Test2.class也位于Bootstrap  Loader可以找到的路径下,所以也被载入了,最后我们看到Test1.class与Test2.class都是由Bootstrap  Loader(null)载入。

测试二: <JRE所在目录>\classes下 Test1.class

<JRE所在目录>\lib\ext\classes下 Test1.class Test2.class

D:\my下 Test1.class Test2.class

dos下输入运行命令,结果如下: D:\my>java Test1 Null Exception in thread “main” java.lang.NoClassdefFoundError:Test2 at Test1.main。。。 D:\my>

从输出结果我们可以看出,当AppClassLoader要载入Test1.class时,先请其Parent,也就是ExtClassLoader来载 入,而ExtclassLoader又请求其Parent,即Bootstrap Loader来载入Test1.class. 由于  <JRE所在目录>\Classes目录为Bootstrap Loader的搜索路径之一,所以Bootstrap  Loader找到了Test1.class,因此将它载入,接着在Test1.class之内有载入Test2.class的需求,由于  Test1.class是由Bootstrap Loader所载入,所以Test2.class内定是由Bootstrap  Loader根据其搜索路径来找,但是因为Bootstrap Loader根本找不到Test2.class(被我们删除了),而Bootstrap  Loader又没有Parent,所以无法载入Test2.class.最后我们看到Test1.class是由Bootstrap  Loader(null)载入,而Test2.class则无法载入

测试三 <JRE所在目录>\classes下

Test2.class

<JRE所在目录>\lib\ext\classes下 Test1.class Test2.class

D:\my下 Test1.class Test2.class

dos下输入运行命令,结果如下: D:\my>java Test1 。。。ExtClassLoader。。。 Null

D:\my>

从输出结果我们可以看出,当AppClassLoader要载入Test1.class时,先请其Parent,也就是ExtClassLoader来载 入,而ExtclassLoader又请求其Parent,即Bootstrap Loader来载入Test1.class.但是Bootstrap  Loader无法在其搜索路径下找到Test1.class(被我们删掉了),所以ExtClassLoader只得自己搜索,因此  ExtClassLoader在其搜索路径  <JRE所在目录>\lib\ext\classes下找到了Test1.class,因此将它载入,接着在Test1.class之内有载 入Test2.class的需求,由于Test1.class是由ExtClassLoader所载入,所以Test2.class内定是由  ExtClassLoader根据其搜索路径来找,但是因为ExtClassLoader有Parent,所以先由Bootstrap  Loader帮忙寻找,Test2.class位于Bootstrap Loader可以找到的路径下,所以被Bootstrap  Loader载入了.最后我们看到Test1.class是由ExtClassLoader载入,而Test2.class则是由Bootstrap  Loader(null)载入

了解了以上规则,请朋友们自行分析以下场景的执行结果

测试四: <JRE所在目录>\classes下

<JRE所在目录>\lib\ext\classes下 Test1.class Test2.class

D:\my下 Test1.class Test2.class

测试五: <JRE所在目录>\classes下

<JRE所在目录>\lib\ext\classes下 Test1.class

D:\my下 Test1.class Test2.class

测试六: <JRE所在目录>\classes下

<JRE所在目录>\lib\ext\classes下

Test2.class

D:\my下 Test1.class Test2.class

测试七: <JRE所在目录>\classes下

<JRE所在目录>\lib\ext\classes下

D:\my下 Test1.class Test2.class

JVM加载Class文件的机制的更多相关文章

  1. Java提高篇——JVM加载class文件的原理机制

    在面试java工程师的时候,这道题经常被问到,故需特别注意. 1.JVM 简介 JVM 是我们Javaer 的最基本功底了,刚开始学Java 的时候,一般都是从“Hello World ”开始的,然后 ...

  2. JVM加载class文件的原理机制(转)

    JVM加载class文件的原理机制 1.Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中 2.java中的 ...

  3. JVM加载class文件的原理

    当Java编译器编译好.class文件之后,我们需要使用JVM来运行这个class文件.那么最开始的工作就是要把字节码从磁盘输入到内存中,这个过程我们叫做[加载 ].加载完成之后,我们就可以进行一系列 ...

  4. 关于JVM加载class文件和类的初始化

    关于JVM加载class文件和类的初始化 1.JVM加载Class文件的原理机制 1.1.装载 查找并加载类的二进制数据 1.2.链接 验证:确保被加载类的正确性.(安全性考虑) 准备:为类的静态变量 ...

  5. jvm 加载class文件过程

    jvm 加载class文件分为装载-链接-初始化三个过程. load -------->link verify prepare resolve     ---------->initial ...

  6. 描述一下JVM加载class文件的原理机制

    Java中的所有类,都需要由类加载器装载到JVM中才能运行.类加载器本身也是一个类,而它的工作就是把class文件从硬盘读取到内存中.在写程序的时候,我们几乎不需要关心类的加载,因为这些都是隐式装载的 ...

  7. JVM加载class文件的原理机制

    Java中的所有类,都需要由类加载器装载到JVM中才能运行.类加载器本身也是一个类,而它的工作就是把class文件从硬盘读取到内存中.在写程序的时候,我们几乎不需要关心类的加载,因为这些都是隐式装载的 ...

  8. 【Java面试题】46 描述一下JVM加载class文件的原理机制?

    JVM中类的装载是由类加载器(ClassLoader)和它的子类来实现的,Java中的类加载器是一个重要的Java运行时系统组件,它负责在运行时查找和装入类文件中的类.  由于Java的跨平台性,经过 ...

  9. 描述一下JVM加载class文件的原理机制?

    JVM中类的装载是由类加载器(ClassLoader)和它的子类来实现的,Java中的类加载器是一个重要的Java运行时系统组件,它负责在运行时查找和装入类文件中的类. 由于Java的跨平台性,经过编 ...

随机推荐

  1. 洛谷 P2218 [HAOI2007]覆盖问题 解题报告

    P2218 [HAOI2007]覆盖问题 题目描述 某人在山上种了\(N\)棵小树苗.冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄膜把这些小树遮盖起来,经过一番长久的思考,他 ...

  2. bzoj

    准确率爆棚啊,然而

  3. 前缀统计 [Trie]

    前缀统计 描述 给定N个字符串S1,S2...SN,接下来进行M次询问,每次询问给定一个字符串T,求S1-SN中有多少个字符串是T的前缀.输入字符串的总长度不超过10^6,仅包含小写字母. 输入格式 ...

  4. IOI1998 Polygon [区间dp]

    [IOI1998]Polygon 题意翻译 题目可能有些许修改,但大意一致 多边形是一个玩家在一个有n个顶点的多边形上的游戏,如图所示,其中n=4.每个顶点用整数标记,每个边用符号+(加)或符号*(乘 ...

  5. Out of memory due to hash maps used in map-side aggregation解决办法

    在运行一个group by的sql时,抛出以下错误信息: Task with the most failures(4): -----Task ID:  task_201411191723_723592 ...

  6. Firefox多国语言多OS离线安装包

    Download Firefox in your language Firefox is made in large part by volunteers around the world. That ...

  7. Chocolatey 使用

    最近空了下来不干点什么就感觉脑袋热,可是出过的问题挖过的坑还是要自己去解决. 一直网络不好安装choco一直都是报错,今天又建立了chocolatey 在windows上来用,网络问题解决了,类似于m ...

  8. bzoj 3190 维护栈

    我们可以将每一辆赛车看成一条直线,斜率为速度,纵截距为初始位置,那么问题就转化为求这n条直线处于最上面的直线.最上面是指在坐标系中,假设从x轴向下看,能看到的直线,只露一个点也算能看见.那么就类似水平 ...

  9. 如何保护自己的windows系统

    最近一段时间给windows做加固防护,积累了几个小工具. 1.杀毒:火绒+火绒剑,windows10 自带的杀毒Windows Defender 2.日志记录:    sysmon sysmon用来 ...

  10. python 学习笔记 aiohttp

    asyncio可以实现单进程并发IO操作,如果仅用在客户端,发挥的威力并不大,如果把asyncio用在服务器端,由于http链接就是IO操作, 因此可以用单线程+coroutine实现多客户的高并发支 ...