类加载的过程

https://crowhawk.github.io/2017/08/21/jvm_5/

上面这个链接和书本的一起看感觉更清晰些,虽然大部分都差不多

一个类的生命周期是: 加载,连接(验证,准备,解析),初始化,使用,卸载,

解析有可能在初始化之前也有可能在初始化之后,(为了搭配动态绑定也是运行时绑定),

何时进行初始化?

加载是有虚拟机自己决定什么时候开始加载的,但是遇到下列的情况就要马上进行初始化:

1:遇到 putstatic ,getstatic ,new ,invokestatic的字节码命令时  比如说,new一个实例化对象,调用别的静态方法, 设置或读取一个类的静态变量,(如果是final修饰的字段不算,在编译期已经加入了常量池)

2.使用反射调用这个类时,如果还没进行初始化,要先初始化

3:如果这个类触发了初始化了,但是父类还没初始化,要先初始化父类

4:虚拟机启动时,要先指定一个要执行的主类(带mian方法的),会先初始化这个主类

5:在动态语言中,如果一个java.lang.invoke.MethodHadle实例的解析结果是REF-gerstatic,REF-putstatic,REF-invokestatic的方法曲柄,这个方法曲柄对应的类没有进行初始化,则需要先触发其初始化

(通过子类来访问父类的静态字段,只会触发父类的初始化,不会引起子类的初始化)

加载:

1:通过全限定名获取这个类的二进制字节流

1.1从ZIP包读取,这很常见,最终成为日后JAR、EAR、WAR格式的基础。

1.2从网络中获取,这种场景最典型的应用是Applet。

1.3运行时计算生成,这种场景使用得最多得就是动态代理技术,在java.lang.reflect.Proxy中,是

用了ProxyGenerator.generateProxyClass的代理类的二进制字节流。

1.4由其他文件生成,典型场景是JSP应用,即由JSP文件生成对应的Class类。

1.5从数据库读取,这种场景相对少见,例如有些中间件服务器(如SAPNetweaver)可以选 

择把程序安装到数据库中来完成程序代码在集群间的分发。

2:把这个二进制字节流代表的静态存储结构转存为方法区运行时的数据结构

3:在内存中生成一个class对象,作为方法区这个类的各个数据的访问入口

连接

1.验证:是连接的第一步,保证calss文件中二进制字节流没有包含危及虚拟机的信息.

1.1:文件格式校验  这个校验是基于字节流校验的,后续的三个校验就是在方法区的储存结构进行的,不会再直接操作字节流了,

1.2:元数据检验:对字节流描述信息进行语义分析,保证其描述符合java语言规范的要求,主要对类的元数据信息进行语义校验

1.3:字节码校验:通过数据流和控制流分析之后,确定语义是合法的,主要对类的方法体进行校验,保证类在运行时不会有危害虚拟机的操作

1.4:符号引用校验:对类自身以外的信息(常量池中各个符号引用)进行匹配校验.发生在虚拟机把符号引用 转为直接引用的时候,在连接的第三阶段--解析时发生

2.准备:

为类变量分配内存并设置初始值(为0或者为null)的阶段,这些变量都在方法区中.不包括实例对象,实例对象会在对象实例化时随对象一起分配在java堆中.

如果是final修饰的则没有初始值,直接为属性的那个值

3:解析:是虚拟机将常量池中的符号引用转为直接引用

符号引用(Symbol References): 符号引用以一组符号来描述所引用的目标,符号可以是

任何形式的字面量,只要使用时能无歧义地定位到目标即可。符号引用与虚拟机实现的内存布局

无关,引用的目标并不一定已经加载到内存中。各种虚拟机实现的内存布局可以各不相同,但是

它们能接受的符号引用必须一致,因为符号引用的字面量形式明确定义在Java虚拟机规范的

Class文件格式中。

直接引用(Direct References): 直接引用可以是直接目标的指针、相对偏移量或是一个

能间接定位到目标的句柄。直接引用是和虚拟机实现的内存布局有关的,同一个符号引用在不同

虚拟机实例上翻译出来的直接引用一般不会相同。如果有了直接引用,那么引用的目标必定已经

在内存中存在

4:初始化:这完全是虚拟机自己做的.程序员没办法影响到这初始化的过程,初始化阶段即虚拟机执行类构造器<clinit>()方法的过程。

4.1.<clinit>()方法是由编译器自动收集类中所有类变量的赋值动作和静态语句块(static{} 块)中的语句合并产生的,编译器收集的顺序由语句在源文件中出现的顺序决定,特别注意的是,静态语句块只能访问到定义在它之前的类变量,定义在它之后的类变量只能赋值,不能访问

4.2.<clinit>()方法与类的构造函数(或者说实例构造器<init>() 方法)不同,不需要显式的调用父类的()方法。虚拟机会自动保证在子类的<clinit>()方法运行之前,父类的<clinit>()方法已经执行结束。因此虚拟机中第一个执行<clinit>()方法的类肯定为java.lang.Object

4.3.由于父类的<clinit>()方法先执行,也就意味着父类中定义的静态语句块要优于子类的变量赋值操作

4.4<clinit>()方法对于类或接口不是必须的,如果一个类中不包含静态语句块,也没有对类变量的赋值操作,编译器可以不为该类生成<clinit>()方法

4.5.接口中不可以使用静态语句块,但仍然有类变量初始化的赋值操作,因此接口与类一样都会生成<clinit>()方法。但接口与类不同的是,执行接口的<clinit>()方法不需要先执行父接口的<clinit>()方法。只有当父接口中定义的变量使用时,父接口才会初始化。另外,接口的实现类在初始化时也一样不会执行接口的<clinit>()方法

4.6.虚拟机会保证一个类的<clinit>()方法在多线程环境下被正确的加锁和同步,如果多个线程同时初始化一个类,只会有一个线程执行这个类的<clinit>()方法,其它线程都会阻塞等待,直到活动线程执行<clinit>()方法完毕。如果在一个类的<clinit>()方法中有耗时的操作,就可能造成多个进程阻塞,在实际过程中此种阻塞很隐蔽

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,302评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,232评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,337评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,977评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,920评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,194评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,638评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,319评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,455评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,379评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,426评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,106评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,696评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,786评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,996评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,467评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,043评论 2 341

推荐阅读更多精彩内容

  • 前面一篇讲解了类加载的时机,现在来看看 类加载的过程 是怎样的。 目录 一、加载二、验证三、准备四、解析五、初始化...
    panning阅读 425评论 0 0
  • 类的生命周期如下图所示 类加载的全过程包括加载,验证,准备,解析,初始化这五个阶段。本篇文章我们来了解Java虚拟...
    小杰的快乐时光阅读 624评论 0 0
  • 上篇文章提到过,类加载一共七步骤:加载、验证、准备、解析、初始化、使用、卸载。现在讲解前五步骤。 一、加载在类加载...
    编程界的小学生阅读 592评论 0 3
  • 一、类加载的时机 类从被加载到虚拟机内存中开始,到卸载出内存为止,其生命周期包括:加载、验证、准备、解析、初始化、...
    我爱谦谦阅读 346评论 0 0
  • 声明:本文摘抄自《深入理解Java虚拟机》一书,本文完全为自我学习,请感兴趣的同学购买正版,支持原创 加载 “加载...
    Chengyu_l阅读 294评论 0 0