JVM类加载机制总结
1.运行时加载优点
提高灵活性,可以在运行时动态加载,连接。例子:面向接口编程,动态绑定实现类(但C++也有动态绑定,说明动态绑定不一定通过运行时加载Class字节码实现,也可能是机器码支持的)
2.编译并在运行时动态加载字节码优点
可在运行时动态获取二进制字节流作为动态代码,比如可以从网络上获取;可以做一个循环,动态从某文件库获取;可以从指定的ClassPath路径获取,比如一个jar包目录
3.与动态类型语言的区别
动态类型语言如JS,可在运行时添加类型属性,方法,在运行时改变类型行为
4.类加载生命周期
加载、验证、准备、解析、初始化、使用、卸载。按这个顺序开始,但交叉执行。验证、准备、解析统称为连接。解析阶段不一定按这个顺序,可以在初始化之后,为了支持上文的动态绑定(运行时绑定)。
5.必须“初始化”(类加载第5阶段)的几种情况(主动引用,有且仅有这些情况时要初始化,初始化钱当然要先“加载”,所以也是必须加载的几种情况)
new实例化对象、读取或设置类static非final字段(final static在编译时存入常量池)、调用类静态方法、类反射调用、初始化一个类时先初始化其父类、虚拟机启动的带main方法的执行主类(虚拟机执行入口)等。
6.不会激发“初始化”的情况(被动引用)
a.引用子类使用其父类的static非final字段(直接定义这个字段的类),只会初始化父类,不会初始化子类。子类是否加载、验证(类加载第1,2阶段),取决于虚拟机具体实现,无规定
b.通过数组定义引用类,不会触发该类初始化。这里触发了一个虚拟机自动生成的代表数组的类的初始化,里面有数组相关属性,比如public的length字段(数组长度)
c.一个类引用另一个类的public static final字段,不会初始化另一个类。该字段引用在编译时进入了前一个类(引用类)的常量池中,编译后就与后一个类完全没关系了。
d.接口初始化:不要求初始化其父类接口,这与类初始化不同。只有使用到父接口比如引用其常量时才会初始化父类接口
7.类加载过程
加载阶段:一个非数组类的加载是开发人员可控性最强的,可以使用系统的引导类加载器,也可使用用户自定义类加载器控制字节流获取方式(下面a所述),即重写loadClass方法。数组类由虚拟机创建,其元素类型由类加载器加载。
a.通过类全限定名获取其字节流,方式:zip/jar/war、网络、运行时计算生成(主要指动态代理生成的"*$Proxy"代理类Class文件)、其他文件生成(如jsp)、数据库读取等
b.字节流静态存储结构转换成方法区运行时数据结构
c.内存中生成代表该类的java.lang.Class对象,作为方法区类数据访问入口
验证阶段:
a.文件格式验证:如魔数开头、主次版本号、常量类型、不符合UTF8的编码
b.元数据验证:语义校验,比如是否有父类、是否继承final类(不允许继承)、是否实现接口、是否覆盖了父类final方法(不允许覆盖)
c.字节码验证:数据流与控制流验证,语义是否合法、符合逻辑。方法体校验:操作数栈数据类型是否与指令码使用类型匹配、指令是否跳到方法体外、方法体内类型转换是否有效
d.符号引用验证:符号引用转为直接引用是在解析阶段进行的,这里是对类自身以外(常量池中各种符号引用)的信息进行匹配校验,比如全限定名是否能找到该类、指定类是否有该符号引用所引用的方法和字段、引用的类、方法、字段访问性(private,protected,public,default)是否可被当前类引用,抛出对应IllegalAccessError、NoSuchMethodError等。
准备阶段:
在方法区将类变量(static)分配内存并设置初始值,通常赋类型零值。如public static int value=123;是赋值为0不是123.赋值123是putstatic指令,在类构造器<clinit>()中,是在初始化阶段才执行的。但public static int value=123;则在准备阶段赋值123.
解析阶段:
将常量池内符号引用替换为直接引用。符号引用:目标不一定已加载入内存。直接引用:直接指向目标的指针、相对偏移量或可间接定位的句柄。引入目标必定在内存中存在。
解析的7类符号引用:类或接口、字段、类方法、接口方法、方法类型、方法句柄、调用点限定符。
递归加载这些符号引用解析成直接引用后的那些类、父类、接口、父接口,进内存,然后使用直接引用指向它们。
初始化阶段:
执行类构造器<clinit>()方法的过程。
<clinit>()方法由编译器自动搜集所有类变量赋值动作和static{}块合并产生,顺序由源文件中出现顺序决定。static{}块可赋值在其后定义的变量,但不可访问。
public class Test {
static {
i = 0;//正常编译
System.out.println(i);//非法向前引用!!
}
static int i = 1;
}
父类<clinit>()方法先于子类<clinit>()执行,由虚拟机调用,而不是子类<clinit>()方法调用。因此父类静态块要优先于子类变量赋值动作。(值为多少的面试题)
static class Parent {
public static int A = 1;
static {
A = 2;
}
}
static class Sub extents Parent {
public static int B = A;
}
public static void main(String[] args) {
System.out.println(Sub.B);
}
B值为2.
接口没有静态块。<clinit>()方法用于变量初始化赋值。不需要先执行父类接口<clinit>()方法,使用时执行。实现接口的类初始化也不需要执行接口<clinit>(),使用时执行。
虚拟机保证<clinit>()方法多线程下安全。如多线程执行,其他线程会阻塞,但退出后其他线程也不会再进入执行。同一个类加载器下(一个类与其加载器一起确定唯一性),一个类型只初始化一次!
JVM类加载机制总结的更多相关文章
- JVM基础系列第7讲:JVM 类加载机制
当 Java 虚拟机将 Java 源码编译为字节码之后,虚拟机便可以将字节码读取进内存,从而进行解析.运行等整个过程,这个过程我们叫:Java 虚拟机的类加载机制.JVM 虚拟机执行 class 字节 ...
- JVM总结(四):JVM类加载机制
这一节我们来总结一下JVM类加载机制.具体目录如下: 类加载的过程 类加载过程概括 说说引用 详解类加载全过程: 加载 验证 准备 解析 初始化 虚拟机把描述类的数据从Class文件加载到内存,并对数 ...
- JVM 类加载机制详解
如下图所示,JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程. 加载 加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这个类的java.lan ...
- Java虚拟机(四):JVM类加载机制
1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构 ...
- JVM类加载机制详解(二)类加载器与双亲委派模型
在上一篇JVM类加载机制详解(一)JVM类加载过程中说到,类加载机制的第一个阶段加载做的工作有: 1.通过一个类的全限定名(包名与类名)来获取定义此类的二进制字节流(Class文件).而获取的方式,可 ...
- JVM类加载机制(转)
原文出自:http://www.cnblogs.com/ityouknow/p/5603287.html 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运 ...
- JVM类加载机制详解
引言 如下图所示,JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程. 加载 在加载阶段,虚拟机需要完成以下三件事情: 1)通过一个类的全限定名来获取定义此 ...
- Android动态加载--JVM 类加载机制
动态加载,本质上是通过JVM类加载机制将插件模块加载到宿主apk中,并通过android的相关运行机制,实现插件apk的运行.因此熟悉JVM类加载的机制非常重要. 类加载机制:虚拟机把描述类的数据从C ...
- Java虚拟机(五):JVM 类加载机制
一.JVM 类加载机制 JVM 类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程. 1. 加载: 加载是类加载过程中的第一个阶段,这个阶段会在内存中生成一个代表 ...
- 深入理解JVM虚拟机6:深入理解JVM类加载机制
深入理解JVM类加载机制 简述:虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 下面我们具体 ...
随机推荐
- php 中date显示时间不对与Linux文件乱码问题
php 中date显示时间不对解决办法如下1.修改/etc/php.ini文件 在里头中找到data.timezone =去掉它前面的分号';' 然后设置data.timezone = “Asia/S ...
- requests爬取百度贴吧:python 美女 3
import requests import sys class Tieba(object): def __init__(self, tieba_name, pn): self.tieba_name ...
- soapUI-Properties
1.1.1 Properties 1.1.1.1 概述 - Properties Option Description Toolbar 属性TestStep工具栏 Properties Li ...
- Keepalived安装后出现的问题总结
1. 在配好主从备份之后,发现虚拟IP能ping通,但是访问虚拟IP对应机器上的服务(不是apache或者mysql之类的公用软件)却不成功,这是因为要访问的服务绑定了主机上的一个实体IP不是INAD ...
- 机器学习理论基础学习3.4--- Linear classification 线性分类之Gaussian Discriminant Analysis高斯判别模型
一.什么是高斯判别模型? 二.怎么求解参数?
- ARM_Core的处理器模式与寄存器,结构杂谈
ARM处理器的工作状态:ARM处理器有两种工作状态.在程序的执行过程中,处理器可以在两种工作状态之间切换,并且不影响 相应寄存器中的内容. ARM状态,此时处理器执行32位对齐的ARM指令:BX指令, ...
- 一款优秀的OA办公系统有哪些功能?
OA办公系统解决企业的日常管理规范化.增加企业的可控性.提高企业运转的效率的基本问题,范围涉及日常行政管理.各种事项的审批.办公资源的管理.多人多部门的协同办公.以及各种信息的沟通与传递.可以概括的说 ...
- 完整table
.table-bordered{ border:1px solid #cccccc; } .table { border-spacing: 0;/*设置或检索当表格边框独立时(即border-coll ...
- UVALive - 7261 Xiongnu's Land
思路: 先二分下界,再二分上届. #include <bits/stdc++.h> using namespace std; #define MP make_pair #define PB ...
- C++飞机大战
#include<windows.h> #include"resource.h" #include<stdlib.h> #include<time.h ...