Java的生命周期
. ---- ----------------->
. --- ------------>
.. ------ ------->
.. ------ ------------------->
类的生命周期
.
. ----
. ----
. ----
. ---------
.
.
加载都干了些啥
1. 通过一个类的全限定名来获取定义此类的二进制字节流
2. 将字节流所代表的静态存储结构转化为方法区的运行时数据结构
3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口
补足说明:
1.类的来源可以从 本地目录,ZIP包(JAR,WAR,EAR),网络传输,运行时计算生成(动态代理技术)
2.JAVA中无处不是对象,正如上所说这个类也是一个对象,只不过比普通对象特殊些,称之为类对象,它所存放的地方也比较特殊,在1.7中存放与perm区,在1.8中存放在metaspace区,但跟heap区一样,是线程共享的,也存在OOM的可能。
验证
.
.
.
. --->
准备
1. 为类变量分配内存并设置类变量初始值
补足说明:
1.在这里分配内存的对象是被static修饰的类变量,而不是实例变量,实例变量将会在对象实例化时被分配到Heap中。
2.初始值为0值,而非被赋予的值,但被static final修饰的值为被赋予的值
对类变量的初始化在 后续的初始化阶段进行
如:public static int value=123;--------->在准备阶段为0
public static final int value=123;--->在准备阶段为123
解析
1. 将常量池内的符号引用转换为直接引用
2. 主要针对类,接口,字段,类方法,接口方法,方法类型,方法句柄,调用点限定符等7类符号引用进行转换
初始化
1. 执行类构造器<clinit>()初始化类变量和其他资源
2. <clinit>()自动收集类中所有类变量的赋值操作和静态语句块中的赋值操作,并按照先后顺序初始化 父类的 类变量的赋值操作和静态语句块中的赋值--->子类的 类变量的赋值操作和静态语句块中的赋值
谁主导了类加载
一.显而易见是类加载器(Class Loader)
二.那么都有什么样的类加载器呢,以及分工
1. 启动类加载器(Bootstrap ClassLoader):
使用C++语言实现,是虚拟机自身的一部分,
负责加载<JAVA_HOME>/lib中的符合文件名规范的类
2. 扩展类加载器(Extension ClassLoader):
继承自java.lang.ClassLoader由JAVA语言实现
负责加载<JAVA_HOME>/lib/ext中的符合文件名规范的类
3. 应用程序类加载器(Application ClassLoader):
继承自java.lang.ClassLoader由JAVA语言实现,getSystemClassLoader()中可获得,故也可以叫做系统类加载器
负责加载ClassPath中的符合文件名规范的类
4. 自定义类加载器(User ClassLoader)
三.加载算法:双亲委派模型
由下而上委托:Custom(自定义)->App->Extension->Bootstrap
ps:将加载任务委托给父类加载
由上而下加载:Bootstrap->Extension->App->Custom(自定义)
ps:如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载
这样加载的意义:同一个CLass文件只要被不同类加载器加载,那么这两个类必定不想等。
通过这个带有优先级的层次关系的加载模型,保证了类的安全和稳定,防止核心API被恶意篡改,防止内存中出现多份同样的字节码。
破坏双亲委派模型
. .
.
.
--> -->
.--->