游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

JVM类加载过程

  Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程被称作虚拟机的类加载机制。
  与那些在编译时需要进行连接的语言不同,在Java语言里面,类型的加载、连接和初始化过程都是在程序运行期间完成的,这种策略让Java语言进行提前编译会面临额外的困难,也会让类加载时稍微增加一些性能开销,但是却为Java应用提供了极高的扩展性和灵活性,Java天生可以动态扩展的语言特性就是依赖运行期动态加载和动态连接这个特点实现的。例如,编写一个面向接口的应用程序,可以等到运行时再指定其实际的实现类,用户可以通过Java预置的或自定义类加载器,让某个本地的应用程序在运行时从网络或其他地方上加载一个二进制流作为其程序代码的一部分。这种动态组装应用的方式目前已广泛应用于Java程序之中,从最基础的Applet、JSP到相对复杂的OSGi技术,都依赖着Java语言运行期类加载才得以诞生。
  之前写的Java实战案例:Java类隔离应用:多Jar包支持,就是充分利用了Java这个特性实现的。
  在正式学习下面内容之前,避免因表达而造成的歧义,约定如下内容:类型:后文中提到类型,指类或接口,如果需要精确表达类或接口,会特意说明Class文件:并非只磁盘中编译后的Class文件,而是二进制字节流,可能是从磁盘文件读取,也可能是网络、数据库、内存或动态生成的等
  对于类加载过程,包括加载、连接、初始化三个阶段,每个阶段的作用简单概括如下:
  类加载过程三个阶段要注意类加载过程和类加载阶段两个名词的区别:
  类加载过程:是类加载的整个流程,包括加载阶段、连接阶段、初始化阶段
  类加载阶段:只是类加载过程的第一个阶段加载阶段
  在加载阶段,JVM需要完成下面三件事:通过一个类的全限定名来获取定义此类的二进制字节流将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构在内存中生成一个代表这个类的java。lang。Class对象,作为方法区这个类的各种数据的访问入口
  类加载的最终产物就是堆内存中的Class对象,对于同一个ClassLoader来说,不管某个类被加载多少次,对应到堆内存中,只有一个Class对象。如下图所示:
  虚拟机规范要求类的加载通过类的全限定类名来获取二进制字节流,并没有严格规范获取的途径,这就给开发者很大的想象空间,除了我们平时常见的Class文件以外,还会有如下几种形式:从ZIP压缩包中读取,这很常见,最终成为日后JAR、EAR、WAR格式的基础从网络中获取,这种场景最典型的应用就是WebApplet运行时计算生成,这种场景使用得最多的就是动态代理技术,在java。lang。reflect。Proxy中,就是用了ProxyGenerator。generateProxyClass()来为特定接口生成形式为Proxy的代理类的二进制字节流由其他文件生成,典型场景是JSP应用,由JSP文件生成对应的Class文件从数据库中读取,这种场景相对少见些,例如有些中间件服务器(如SAPNetweaver)可以选择把程序安装到数据库中来完成程序代码在集群间的分发可以从加密文件中获取,这是典型的防Class文件被反编译的保护措施,通过加载时解密Class文件来保障程序运行逻辑不被窥探。。。。。。连接阶段验证
  验证是连接阶段的第一步,这一阶段的目的是确保Class文件的字节流中包含的信息符合《Java虚拟机规范》的全部约束要求,保证这些信息被当作代码运行后不会危害虚拟机自身的安全。
  验证阶段大致会完成下面四个阶段的验证动作:文件格式验证:验证字节流是否符合Class文件格式的规范,并且能被当前版本的虚拟机处理元数据验证:对字节码描述的信息进行语义分析,以保证其描述的信息符合《Java语言规范》的要求字节码验证:整个验证过程中最复杂的一个阶段,主要目的是通过数据流分析和控制流分析,确定程序语义是合法的、符合逻辑的符号引用验证:校验行为发生在虚拟机将符号引用转化为直接引用的时候,这个转化动作将在连接的第三阶段解析阶段中发生
  该阶段开发者可控性弱,而且对我们学习Java开发意义不大,再次不多赘述,想要更详细的学习具体每阶段验证的内容,可以阅读《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)周志明》连接阶段准备
  在准备阶段,会为类中定义的类变量(即静态变量,使用static修饰的变量)分配内存并设置类变量初始值,从概念上讲,这些变量所使用的内存都应当在方法区中进行分配,但必须注意到方法区本身是一个逻辑上的区域,在JDK7及之前,HotSpot使用永久代来实现方法区时,实现是完全符合这种逻辑概念的;而在JDK8及之后,类变量则会随着Class对象一起存放在Java堆中,这时候类变量在方法区就完全是一种对逻辑概念的表述了。
  需要注意区分类变量和实例变量两个概念:类变量:是被static修饰的成员变量,准备阶段分配内存、设置初始值的就是这些变量实例变量:没有被static修饰的成员变量,这些变量是在类实例化时,随着对象的创建一起分配内存到堆中
  在此阶段,类变量设置初始值包括两种情况:
  1、编译后value具有ConstantValue属性
  当类变量是使用static和final修饰,并且代码中赋值类型为基本数据类型或字符串(这里的字符串是双引号赋值,不是newString()),如下所示:publicclassDemo{基本数据类型privatestaticfinalintNUM10;字符串privatestaticfinalStringSTR字符串;}
  使用命令javapvpDemo。class查看编译后的Class文件,如下所示:省略{privatestaticfinalintNUM;descriptor:Iflags:(0x001a)ACCPRIVATE,ACCSTATIC,ACCFINALConstantValue:int10privatestaticfinaljava。lang。StringSTR;descriptor:LjavalangString;flags:(0x001a)ACCPRIVATE,ACCSTATIC,ACCFINALConstantValue:String字符串省略}SourceFile:Demo。java
  可以看到两个变量均生成了ConstantValue属性,对于这种变量,设置初始值就是当前代码中设置的值。
  2、不具有ConstantValue属性
  当类类变量只使用static修饰,或使用static和final修饰,但代码中赋值类型为引用数据类型,如下所示:publicclassDemo{只有static修饰privatestaticintnum10;赋值为引用数据类型privatestaticfinalStringSTRnewString(字符串);}
  使用命令javapvpDemo。class查看编译后的Class文件,如下所示:省略{privatestaticintnum;descriptor:Iflags:(0x000a)ACCPRIVATE,ACCSTATICprivatestaticfinaljava。lang。StringSTR;descriptor:LjavalangString;flags:(0x001a)ACCPRIVATE,ACCSTATIC,ACCFINAL省略}SourceFile:Demo。java
  这类类变量没有生成ConstantValue属性,对于这类变量,设置初始值就是对应类型的默认初始值,比如类变量num初始值为0,STR初始值为null,具体如下:
  各种数据类型初始化零值连接阶段解析
  该阶段开发者可控性弱,而且对我们学习Java开发意义不大,再次不多赘述,想要更详细的学习具体每阶段验证的内容,可以阅读《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)周志明》初始化阶段
  类的初始化阶段是类加载过程的最后一个步骤,之前介绍的几个类加载的动作里,除了在加载阶段用户应用程序可以通过自定义类加载器的方式局部参与外,其余动作都完全由Java虚拟机来主导控制。直到初始化阶段,Java虚拟机才真正开始执行类中编写的Java程序代码,将主导权移交给应用程序。
  在初始化阶段,最主要做一件事,就是执行类构造器()方法(clinit:classinitialize前几个字母的简写),该方法是由编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并产生的,如下所示:publicclassInitStageTest{privatestaticfinalStringSTATICCONSTANT静态常量;privatestaticStringCLASSVARIABLE类变量;static{CLASSVARIABLE类变量重新赋值;}}
  对上面的类进行编译,执行命令javapvpInitStageTest。class查看字节码,如下所示:省略上面内容{privatestaticfinaljava。lang。StringSTATICCONSTANT;descriptor:LjavalangString;flags:ACCPRIVATE,ACCSTATIC,ACCFINALprivatestaticjava。lang。StringCLASSVARIABLE;descriptor:LjavalangString;flags:ACCPRIVATE,ACCSTATICpubliccom。haichun。jvm。InitStageTest();descriptor:()Vflags:ACCPUBLICCode:stack1,locals1,argssize10:aload01:invokespecial1MethodjavalangObject。init:()V4:returnLineNumberTable:line6:0LocalVariableTable:StartLengthSlotNameSignature050thisLcomhaichunjvmInitStageTest;static{};descriptor:()Vflags:ACCSTATICCode:stack3,locals0,argssize00:new7classjavalangString3:dup4:ldc9String静态常量6:invokespecial11MethodjavalangString。init:(LjavalangString;)V9:putstatic14FieldSTATICCONSTANT:LjavalangString;12:ldc20String类变量14:putstatic22FieldCLASSVARIABLE:LjavalangString;17:ldc25String类变量重新赋值19:putstatic22FieldCLASSVARIABLE:LjavalangString;22:returnLineNumberTable:line8:0line10:12line13:17line14:22}SourceFile:InitStageTest。java
  上面输出的信息中static{}其实就是方法
  为了更加直观的看到,可以使用IDEA插件jclasslibBytecodeViewer查看类的字节码信息,如下所示:
  根据方法的字节码可以看到,在该方法中有如下内容:【09】静态常量赋值(除了静态常量的值可以在编译器确定的以外,这类变量具有ConstantValue属性,在连接阶段准备阶段赋值完成,其他类变量只是赋值为默认零值)【1214】类变量赋值【1719】执行静态代码块。
  通过插件可以看到另外一个方法(对应javap命令打印的publicom。haichun。jvm。InitStageTest()),该方法为实例构造器,该方法是在类实例化时调用。要区别方法,方法为类构造器,是在类加载过程初始化阶段调用。
  实例构造器,其实就是我们代码中定义的构造函数,如果有多个构造函数,就会有多个方法。blockquote
  方法与方法不同的是,不需要显示的调用父类类构造器(方法首先会调用父类实例构造器,如publicom。haichun。jvm。InitStageTest()命令中1:invokespecial1调用Object的构造器),而是由JVM保证子类方法执行前,父类的先执行完成,因此,JVM第一个执行的方法的类型一定是Object。
  由于父类方法先执行,也就意味着父类中定义的静态语句块要优先于子类的变量赋值操作,因此下面示例中字段B的值将会是2不是1:staticclassParent{publicstaticintA1;static{A2;}}staticclassSubextendsParent{publicstaticintBA;}publicstaticvoidmain(String〔〕args){System。out。println(Sub。B);}
  方法对于类或接口来说并不是必需的,如果一个类中没有静态语句块,也没有对变量的赋值操作,那么编译器可以不为这个类生成方法。
  接口中不能使用静态语句块,但仍然有变量初始化的赋值操作,因此接口与类一样都会生成方法。但接口与类不同的是,执行接口的方法不需要先执行父接口的方法,因为只有当父接口中定义的变量被使用时,父接口才会被初始化。此外,接口的实现类在初始化时也一样不会执行接口的方法。
  参考文献
  深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)周志明
  Java高并发编程详解:多线程与架构设计

北京首座国际标准专业足球场新工体落成这是1月6日拍摄的北京工人体育场外景。新华社记者张晨霖摄当日,记者从北京市重大项目办获悉,历时两年多,北京工人体育场改造复建项目足球场主体工程建设任务完成,新工体成为全国……人民日报少年气是经历磨难的来的生逢盛世,我们享受着新时代的和平阳光,书写着新时代的奋斗华章。新长征路上,有风有雨是常态,风雨无阻是心态,风雨兼程是状态。只有以豪迈志气……任正非美国制裁期间华为完成1。3万颗器件的开发【手机中国新闻】近日,手机中国注意到,上海交通大学发布了一篇文章:擦亮花火、共创未来任正非在难题揭榜花火奖座谈会上的讲话的文章。其中,透露出了不少值得关注的信息,感兴趣的网友可……多家银行大额存单额度告急怎么办?每家银行都有大额存单吗?9月财经新势力大额存单存单一般门槛是比较高的,有的需要20万才可以起购,有的门槛比较高的需要30万、50万、100万才可以起购,但大额存款的存款利率是比一般定期存款利率的……故意让消费者看不懂的产品名,是为了掩饰什么在开始今天这篇内容前,我们想先问大家两个问题。那就是酷睿i313100与酷睿i912900KS这两款处理器,哪一个的性能更强?以及RTX4050和RTX3090Ti这两款显卡的……RTX409016GB408012GB40708GB4060一家罗马尼亚零售商列出了NVIDIA下一代GeForceRTX40笔记本电脑阵容,其中包括旗舰产品RTX4090。这家零售商将NVIDIAGeForceRTX4090、RTX4……NBA得分效率值和正负值排名英格拉姆牛,莫兰特前途无限本文数据来源标注在图表标题下方,图表和内容均为安安小小姐姐原创,并开启全网保护,转载引用请联系作者。NBA季后赛,进行到第4天,共安排了6支球队的三场对决。本场比赛……从性价比篮球鞋到科技款篮球鞋怎么选头条创作挑战赛我在头条搞创作第二期秋日生活打卡季篮球鞋李宁李宁冷血Low参考价:359599名字很酷,配置齐全主要科技配置:透气工程网布材质鞋面TPU材质拼接……懂得取舍看到过这样一则故事,一位少年被老师要求把大块石头装进空瓶子里,太大装不进去,老人告诉他,把它敲碎再装,于是少年费好一番功夫把空瓶子整满,但石子间还有空隙呀,于是往里再装沙子,塞……横店影视城横店影视城推荐上面说到义乌火车站有直达到横店影视城专车35元人,如您提前有攻略,可提前一天在美团预定一日游或2日游,会有优惠哦坐横店专车可联系电话我和朋友直接……婴儿血管瘤血管瘤婴儿血管瘤,皮肤科激光钟淑霞医生。看看这样是什么样的皮损,这就是胎记的一种也叫婴儿血管瘤。他出生就有的是不是。患者:出生十多天就有了,出生后十几天对。患者:十几天。……3月底换机推荐这四款耗电低性能强,关键还不贵,用三年不会慢如果您喜欢,可以点击上面的关注二字。后续会为您提供更多有价值的内容。今天分享:3月底换机推荐这四款:耗电低性能强,关键还不贵,用三年不会慢第一款:红米Note10P……
怎么能看出一个人开车水平高低?昨天打滴滴去饭店,去的时候,滴滴显示,司机驾龄超过6年。上车后,司机是个20多岁的年轻人。我坐副驾驶室,觉得司机开车技术挺熟练的,无论是行驶路线、安全距离、行驶速度等拿捏得很到……看了USR和UY,UY没活动,USR店里面便宜一千,怎么选?很高兴回答这个问题。两车对比两个车都是很皮实的小踏板,UY是济南铃木的,也是UU升级版,把外型做的时尚漂亮了一些,当然这是相对老气的UU而言的,漂不漂亮真的每个人的眼光不……被硅谷银行破产风波波及一场虚惊后九安医疗百亿资金去向何方公司在硅谷银行的存款已可以全额使用,并未受到损失。3月14日早间,九安医疗发布公告,更新了硅谷银行存款的最新动态。被卷入硅谷银行破产风波的九安医疗,经历了一场虚惊。不过九……无缘世少赛!中国队落寞离场,目睹韩国球员拥抱庆祝,跪地怒吼2022年U18男排亚少赛14决赛,中国男排苦战5局,23不敌韩国队,无缘4强,同时也无缘2023年男排世少赛参赛资格。决胜局,中国队1315功亏一篑,而韩国队员疯狂庆祝,跪地……早餐与健康息息相关,提醒2类早餐不要长期吃,会慢慢伤身早餐是每个人都耳熟能详的一件事,而健康早餐的标准就是营养均衡。很多上班族由于工作的原因以及其他原因所影响,很多上班族都没有吃早餐的习惯。但殊不知这个习惯很容易会造成亚健康……有哪些车口碑和销量不行,但质量却很好?最冤的肯定是国产先说口碑国产车的口碑不行,这要从两方面来说,过去国产车是真不行,买国外淘汰下来的生产线,还特么得花大价钱,用三菱的发动机,弄手动变速箱。说实话那时候……30万你会选择哈弗H9顶配,还是三菱帕杰罗,两款车差距大吗?2。0TH9对比3。8帕杰罗论动力,H9完胜!论内饰,H9完胜!论空间,帕杰罗完胜,尤其是放倒第三排后,后备箱空间,帕杰罗超大!论可靠性,帕杰罗完胜!……拿到驾驶证后三年内没开过车,现在想买车,但是又担心开车技术不三年算什么,说说我的经历:(驾照)练车到拿到驾照,车上时间加起来应该没有4小时;拿证之后,整整10年没有摸过车!(买车)试车找熟人试,取车找熟人取;(练……撼路者值得购买吗?江铃福特撼路者是一款不错的硬派越野SUV车型,尽管它长得不太硬派,但是非承载式的车身结构,227mm的离地间隙,最大涉水深度800mm这些参数又在无时无刻的提醒这是一款纯越野车……老百姓买得起的轿车,遮风挡雨没问题,艾瑞泽5的实力究竟如何?艾瑞泽5颜值高、实力强、有担当。艾瑞泽5采依然延续家族式外观设计,在细节上进行更运动的调整,同时内饰和配置均上也有一定程度的升级。同时在颜值、互联、操控、动力和安全……全球手机销量排行榜出炉第1名为诺基亚,销量50亿台ITBEAR科技资讯1月13日消息,知名数码博主科技新一在近日带来有关全球手机销量排行榜的最新消息,得知第1名是诺基亚品牌,销量为50亿台。不仅如此,该博主还带来了与此相……海边拍照阴天滤镜分享神仙滤镜海边拍照阴天滤镜分享神仙滤镜啊啊啊我简直太喜欢海边了调色工具醒图滤镜风景克莱因克莱因57光感7对比度26饱和度15锐化20……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网