类加载实际上并不复杂,我们知道Java是面向对象的编程语言,程序的运行过程中无时不刻不与类和对象打交道。而类加载是程序运行的第一步。
实际上一般来说一个Java程序的完整运行有一下几步:
1.编译:就是将我们编写的代码编译成字节码,没什么好说的。有时间的话,我会写一些有关字节码结构的文章,期待吧。
2.装载:就是说找到类的.class文件,然后将这种二进制的文件数据加载到内存中
3.链接:链接比较复杂,它一共有三个步骤。
(1).验证
就是验证一个类文件中的字节码的合法性正确性
(2).准备
将一个类中所有的静态变量分配内存,并且给他们初始化一个默认值。
(3).解析
我们在编写代码的过程中除了有基本变量之外,还有一些引用变量。而解析的过程就是将这些引用变量的地址为对应类存在的地址。
4.初始化:
初始化的概念比较简单,就是给Java类中所有的成员变量与静态变量赋一个初始值,如果我们在编写的时候有说明该变量值则为该值,如果没有说明该变量的值是什么则保留它的默认值。
初始化有一个比较特殊的概念,就是说所有的类只初始化一次,并且初始化实在第一次直接调用它的时候才会初始化。在Java中对类的直接初始化调用有7中分别是:
除了上面所说的这7中之外,其他的全部都是间接调用。也就不会导致类的初始化
5.使用: 就是正常的使用啊,各种创建实例调用方法等等
6.卸载:放一个类不再被使用的时候就可以被卸载了,当然其条件又很多。
上面的呢就是类加载的一个过程,在类加载的过程中呢最为核心的一个方面呢就是关于类加载器的知识。
Java的类加载过程中最最逃不开的就是有类加载器了,因为我l们要想创建一个类的实例,首先在内存中你就要有一个类的class对象,要想有这个class对象就要通过类加载。
在Java中呢一盘情况下有两种类型的加载器
第一种:Java自带的类加载器:
Java自带的类加载器有三个
第二种:自定义类加载器:
这个Java中类加载器如下图所示:
每一个类加载器所能加载的类都是不同的。
Java的类加载呢使用的是双亲委派机制,如下图所示:
这个图有些大,不过也没关系啦。具体来说双亲委派机制就是说,加入我现在有一个自定义的类加载器(MyClassLoader)要加载这个Class1类,这个类加载器呢并不是由它直接加载,而是交给它的父加载器来加载这个类。在这个图里面呢也就是交给(System/App ClassLoader)来加载这个类。到了System/App ClassLoader的时候呢也是交给它的父加载器,一直直到根加载器。
到了根加载器之后首先会判断当前类有没有被加载,如果有被加载的话则不再重复加载,如果没有被加载的话判断这个类能不能被根加载器加载,如果不能则交给根加载器的子加载器区加载,知道将这个类加载到内存中。
为什么要双亲委派呢,首先明确一点:jvm如何认定两个对象同属于一个类型,必须同时满足下面两个条件:
就类似于写一个java.lang.System类能不能够被加载呢,实际上时不能被加载的,因为所有的类是由BootStrap首先加载的,当你写了一个java.lang.System的时候想让它加载的时候,BootStrap已经加载完成了系统自带的java.lang.System就不可能加载你自己写的java.lang.System类了。
关于JVM的一些知识有类加载,JVM内存,Java字节码助记符,垃圾回收。不一定一次写完,能写多少是多少把
原文:https://www.cnblogs.com/leiroliu/p/11846006.html